Search code examples
webpackwebpack-2

Webpack 2+: How to apply different loaders for files with same extension?


Here's my use-case: Most svgs should be inlined. So I setup a rule like this:

{test: /\.svg$/, use: "svg-inline-loader"},

In some instances I just want the url of an svg rather than inlining it. In webpack 1.x I required them like this: require('path/to/file.svg?external').

Here's the corresponding rule:

{test: /\.svg\?external$/, use: "file-loader!image-webpack-loader"},

It seems like webpack 2 does not include the ? part anymore when testing for a rule since only the first rule is being applied to all my svgs after migrating.

Is there a way around this? Is there maybe a different strategy of how to apply different set of loaders for files of the same extension when requireing them?

PS: I'm aware that I could require the file like this: require('!file-loader!image-webpack-loader!path/to/file.svg') but my loaders are a bit more complex than this and I don't want to repeat their configuration all the time.

PSS: This doesn't seem to work either (it still only applies the first rule)

{test: /\.svg$/, use: "svg-inline-loader", exclude: /\?external/},
{test: /\.svg$/, use: "file-loader?!image-webpack-loader", include: /\?external/}

Solution

  • So I recently attended a talk by webpack's Juho Vepsäläinen and found the answer in this slide:

    {
      test: /.css$/,
    
      oneOf: [
        {
          resourceQuery: /inline/, // foo.css?inline
          use: 'url-loader',
        },
        {
          resourceQuery: /external/, // foo.css?external
          use: 'file-loader',
        },
      ],
    }
    

    resourceQuery to the rescue!