How to use multiple configuration files in webpack?

21,898

Solution 1

There are some ways to accomplish that. Perhaps the simplest one is specifying the config file to use. Read more about webpack usage with config file.

Add another script in your package.json with:

"build": "webpack --config ./path-to/webpack.config.prod.js"

Place your production config object inside webpack.config.prod.js.


Another way is using the npm lifecycle event. Update your current webpack.config.js script to check the target script and decide which config to use:

const TARGET = process.env.npm_lifecycle_event;
if (TARGET === 'dev') {
   module.exports = require('./path-to/webpack.config.dev.js');
}
if (TARGET === 'build') {
   module.exports = require('./path-to/webpack.config.prod.js');
}

You can find previous approach in this webpack-demo project on GitHub.

Solution 2

A few options:

  1. use webpack-merge

  2. use multiple configurations and choose between them using the --config-name option

  3. If you don't mind changing your webpack config object (module.exports) into a function as described here you could do something like this in your webpack.config.js:

    module.exports = (env, argv) => {
         return {
            //your config here, do something with the mode
               mode: env.mode
            };
        };
    

and pass the mode into your config by invoking webpack with the --env flag:

npx webpack --env mode=development

Or just add it to your package.json like this:

  "scripts": {
      "watch": "webpack --watch --env mode=development",
      "build": "webpack --env mode=production"
    }

Although if all you want is to toggle the mode you could just use the --mode flag

Solution 3

In watch mode you can run webpack with NODE_ENV prefix from package.json, for example:

{
  ...
  "scripts": {
    "watch": "NODE_ENV=development webpack --watch",
    "build": "NODE_ENV=production webpack",
    ...
  }
}

and then use that preset (process.env.NODE_ENV) in webpack.config.js:

const mode = process.env.NODE_ENV;

const config = {
  mode,
  // ... common configuration
};

if (mode === 'development') {
  // update config object for development
} else if (mode === 'production') {
  // update config object for production
}

module.exports = config;

Solution 4

The npm module webpack-merge is a confortable way of having multiple configuration files in webpack. It allows to have a common configuration file and several other that "extend" from this one as the following example will show.

Installing

npm install webpack-merge

Common webpack config file

This would be where the common configurations between your other files are.

webpack.common.js

const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const { CleanWebpackPlugin } = require("clean-webpack-plugin");

module.exports = {
  entry: "./src/index.js",
  plugins: [
    new CleanWebpackPlugin(),
    new HtmlWebpackPlugin({
      title: "Output Management",
      template: "src/index.html",
    }),
  ],
  output: {
    filename: "bundle.js",
    path: path.resolve(__dirname, "dist"),
  },
};

Extending files

I decided to use development and production configuration files for the example but any amount can be used.

webpack.dev.js

const path = require("path");

const { merge } = require("webpack-merge");
const common = require("./webpack.common.js");

module.exports = merge(common, {
  mode: "development",
  devServer: {
    contentBase: path.join(__dirname, "dist"),
    compress: true,
    port: 9000,
  },
});

webpack.prod.js

const { merge } = require("webpack-merge");
const common = require("./webpack.common.js");

module.exports = merge(common, {
  mode: "production",
});

In both you import the merge function and use it to create your files without having to duplicate code. In your scripts you can simply call the extending configuration files like so.

package.json

...
"scripts": {
  "build": "webpack --config webpack.prod.js",
  "dev": "webpack serve --config webpack.dev.js"
},
...
Share:
21,898

Related videos on Youtube

Kousher Alam
Author by

Kousher Alam

Updated on January 03, 2022

Comments

  • Kousher Alam
    Kousher Alam over 2 years

    I'm building a webpack automated workflow. I completed the development server. All of my development configurations are in webpack.config.js file.

    Then, I add it into package.json script via 'dev':'webpack-dev-server'

    How would one make a configuration for production in a separate file?

    • VimNing
      VimNing about 2 years
      But what's the real advantage to have so many webpack configs?
  • Jonathan
    Jonathan about 5 years
    If the files have commonalities, how would one include the commonalities (i.e. a webpack.config.core.js)?
  • Carloluis
    Carloluis about 5 years
    You might extract those commonalities into a third config file as you mentioned (e.g.: webpack.common.js). That script is then referenced and its config is extended with the environment specific parts. Hint: webpack-merge is commonly used for this task. Hope this comment answers part of your question. If not, feel free to create a question with more information and give me a reference to check it out.
  • VimNing
    VimNing about 2 years
    But what's the real advantage to have so many webpack configs?
  • VimNing
    VimNing about 2 years
    But what's the real advantage to have so many webpack configs?
  • VimNing
    VimNing about 2 years
    But what's the real advantage to have so many webpack configs?
  • jogarcia
    jogarcia about 2 years
    @Rainning It depends on the complexity of the app you are building. A dev build usually is bigger and heavier but it has better error support and warnings while a production environment is the other way around. You can't have both things the same time