10

Is is possible to run two separate loader chains for the same extension?

In my case, I want to run one set of loaders to build a static file, and another to write a different set of files (for server side rendering)

  {
    test: /\.p?css$/,
    use: ExtractTextPlugin.extract([ "css-loader", "postcss-loader" ]),
  },
  {
    test: /\.p?css$/,
    use: [  
      {
        loader: "emit-file-loader",
        options: {
          name: "dist/[path][name].pcss",
        },
      },
      {
        loader: "skeleton-loader",
        options: {
          procedure: function (content) {
            return `module.exports = ${content}`
          },
        },
      },
      "postcss-loader",
    ]),
  }

But according to What is the loader order for webpack? it seems to run all loaders in the same chain, even if they're defined in separate rules.

Maybe I'm not understanding loaders fully, but is there a way to have each set of loaders (the use list) run independently?

Craig Kochis
  • 873
  • 1
  • 8
  • 21
  • I haven't tried but I would look into creating a custom plugin. Hooking into specific events manually might make it possible to do two things with same file. Some time ago I came across [this](https://github.com/leftstick/unminified-webpack-plugin) that outputs both minified and unminified files. Might be helpful since your use case sounds similar – laggingreflex Jul 20 '17 at 13:57

2 Answers2

3

I found a loader which is best suited for your case multi loader. This loader requires a module multiple times, each time loaded with a different loader. Like in a multi entry point the exports of the last item are exported.

var multi = require("multi-loader");
{
    module: {
        loaders: [
            {
                test: /\.css$/,
                // Add CSS to the DOM
                // and
                // Return the raw content
                loader: multi(
                    "style-loader!css-loader!autoprefixer-loader",
                    "raw-loader"
                )
            }
        ]
    }
}

or you can require same file twice using inline loaders at require statement like this

import Styles from 'style-loader!css-loader?modules!./styles.css';
import Styles from 'xyz-loader!sass-loader?modules!./styles.css';

and you can pass the configration option as query.

Also you can make alias for loader-name and configration and use that insted of writing loader-name and configration every time like this

in config file

resolveLoader: {
  alias: {
    myLoader1: "style-loader!css-loader?modules", // and much more
    myLoader2: "xyz-loader!sass-loader?modules" // and much more
  }
}

at import

import Styles from 'myLoader1!./styles.css';
import Styles from 'myLoader2!./styles.css';
ecbrodie
  • 11,246
  • 21
  • 71
  • 120
Tripurari Shankar
  • 3,308
  • 1
  • 15
  • 24
1

You can include and exclude files using Regular Expression on each rule.

In the Condition section of the documentation, they list some possible values those properties accept. Here some I think that could help you:

  • A string: To match the input must start with the provided string. I. e. an absolute directory path, or absolute path to the file.
  • A RegExp: It's tested with the input.
  • A function: It's called with the input and must return a truthy value to match.

I've used the RegExp approach in a project, separating the special case in a specific folder. So in the the webpack config I included the folder in one set of rules and excluded from the other. For example:

{
  test: /\.p?css$/,
  include: /specific_folder/,
  use: ExtractTextPlugin.extract([ "css-loader", "postcss-loader" ])
},
{
  test: /\.p?css$/,
  exclude: /specific_folder/,
  use: [  ... ]
}
  • Ideally, I want the same files to be processed in each. Once, to generate a CSS file, and another to build the modules being referenced from JS. If these had the same conditional, would it execute both of them separately? Or would there only be one output (and they'd be chained) – Craig Kochis Jul 19 '17 at 17:56
  • With the same conditions I'm almost sure it would behave the same as no condition. I'm not sure if I got what you are trying to do, but if you need two different outputs, I think you need two entry points. Is [this](https://stackoverflow.com/q/42213478/1096013) similar to your problem? – Daniel Abrahão Jul 19 '17 at 21:00
  • Yeah, it's similar to that, thanks! Basically, I want to run the code through ExtractTextPlugin, but also have the code included in the build. It's sounds like that might not be possible with only one entry point. – Craig Kochis Jul 19 '17 at 21:42