Home > Enterprise >  How to stop the Vue compiler from handling static assets
How to stop the Vue compiler from handling static assets

Time:11-08

My Vue 3 app references a number of static assets. The static assets are already set up with their own file structure, which happens to be outside of the app source directory. My web server has been configured for this and happily serves files from both the Vue build directory and the static assets directory.

The Vue compiler, however, is not so happy. When it sees a path, it tries to resolve it and copy the asset to the build directory. If I use an absolute path it cannot find the asset, and crashes and dies.

Requirement

I would like the Vue compiler to only output css and js files. I do not need the static files in the build directory. If the Vue compiler sees a reference to a static file - eg:

<style lang="scss">
.hero {
    background-image: url('/images/background.jpg');
}
</style>

it should not try to resolve /images/background.jpg and copy it to the build directory; it should assume that I have already put the file where it needs to be.

Current setup

I'm using Vue 3 and Webpack 5. My webpack.config.js is

const MiniCssExtractPlugin = require( 'mini-css-extract-plugin' )
const { VueLoaderPlugin } = require( 'vue-loader' )
const path = require( 'path' )

module.exports = {
    entry: './src/index.ts',
    mode: 'production',
    module: {
        rules: [ {
            test: /\.vue$/,
            loader: 'vue-loader'
        }, {
            test: /\.ts$/,
            loader: 'ts-loader',
            exclude: /node_modules/,
            options: {
                appendTsSuffixTo: [ /\.vue$/ ]
            }
        }, {
            test: /\.s?css$/,
            use: [
                MiniCssExtractPlugin.loader,
                'css-loader',
                {
                    loader: "sass-loader",
                    options: {
                        additionalData: '@import "@/util/sass/_index.scss";' // import _index.scss to all Vue components
                    }
                }
            ]
        } ]
    },
    plugins: [
        new MiniCssExtractPlugin( {
            filename: 'style.css'
        } ),
        new VueLoaderPlugin(),
    ],
    resolve: {
        alias: {
            '@': path.resolve( __dirname, 'src' )
        },
        extensions: [ '.ts', '.scss', '.vue' ],
    },
    output: {
        filename: 'app.js',
        path: path.resolve( __dirname, 'build' ),
    },
}

CodePudding user response:

You need to tell Webpack to disable asset emission.

By default, asset/resource modules are emitting with [hash][ext][query] filename into output directory.

Since you haven't specified anything concerning asset resources in your webpack config, it will emit a file for each ressource.

As a side note, your vue-loader will not modify absolute paths :

If your static asset URL is specified with an absolute path, Vue will preserve as-is

So, for your concern, make sure to add a rule in your webpack config targeting your asset types. Make sure this rule is the first one run (the last one in your rules array).

//...
module: {
    rules: [
      //...
      {
        test: /\.(png|jpe?g|gif|svg|eot|ttf|woff|woff2)$/i,
        type: 'asset/resource',
        generator: {
          emit: false,
        },
      },
    ],
},
//...

Here is the webpack reference for more information

  • Related