Vue-cli: Cannot fully override rule in Webpack config

Created on 29 Mar 2018  路  5Comments  路  Source: vuejs/vue-cli

Version

3.0.0-beta.6

Reproduction link

https://github.com/divyamrastogi/config-override-bug-demo

Steps to reproduce

Go to App.vue to see the loading of the SVG asset. The SVG contents is displayed in the view.

What is expected?

svg-sprite-loader is not being used (setup in vue.config.js) to process SVG files. The Star data property should be an object after being processed by this loader.

What is actually happening?

The SVG is still being processed with file-loader from the default Webpack configuration and is therefore returning a string. It appears the config makes no difference to the processing of the SVG.

Most helpful comment

You probably expected the merge to replace the file loader, but webpack-merge isn't that clever - it doesn't compare test regexp's to find which rule should be replaced, it simply appends the new rule to the array of existing ones.

So: You didn't remove the file-loader that already tests for .svg itself (this one). You add the svg-sprite-loader later, it's lower priority - so file-loader processes the file, and your loader never gets any work.

But you can use webpack-chain to remove the old loader and add yours in its place:

module.exports = {
  chainWebpack: config => {
    // remove the old loader
    config.module.rules.delete('svg')

    // add the new one
    config.module.rule('svg')
      .test(/\.(svg)(\?.*)?$/)
      .use
        .loader('svg-sprite-oader')
        .options({
          name: "[name]-[hash:7]",
          prefixize: true
        })

  }
}

Relevant webpack-chain docs: https://github.com/mozilla-neutrino/webpack-chain#config-module-rules-uses-loaders-creating

All 5 comments

You probably expected the merge to replace the file loader, but webpack-merge isn't that clever - it doesn't compare test regexp's to find which rule should be replaced, it simply appends the new rule to the array of existing ones.

So: You didn't remove the file-loader that already tests for .svg itself (this one). You add the svg-sprite-loader later, it's lower priority - so file-loader processes the file, and your loader never gets any work.

But you can use webpack-chain to remove the old loader and add yours in its place:

module.exports = {
  chainWebpack: config => {
    // remove the old loader
    config.module.rules.delete('svg')

    // add the new one
    config.module.rule('svg')
      .test(/\.(svg)(\?.*)?$/)
      .use
        .loader('svg-sprite-oader')
        .options({
          name: "[name]-[hash:7]",
          prefixize: true
        })

  }
}

Relevant webpack-chain docs: https://github.com/mozilla-neutrino/webpack-chain#config-module-rules-uses-loaders-creating

@LinusBorg I see. It seems to work thanks. How would I go about applying multiple loaders in this way? Like, svg-fill-loader and svgo-loader too? Thanks.

I'm not familiar with those loaders, how would a "normal" config look like that uses them together?

hey @michaelpumo,

You can combine chainWebpack and webpack merge like in #1045
Take a look at this vue.config.js

@LinusBorg Maybe we should have a cookbook reciepe specifically for the SVG loader as this question seems to come up quite a lot. What do you think?

@LinusBorg Maybe we should have a cookbook reciepe specifically for the SVG loader as this question seems to come up quite a lot. What do you think?

I haven't seen this question before, so I can't say much about the relevance. But feel free to make a suggestion for the cookbook!

I'll close this issue as the original question was answered. Further discussions can happen on forum.vuejs.org or chat.vuejs.org

Was this page helpful?
0 / 5 - 0 ratings