Kousher Alam
Kousher Alam

Reputation: 1055

How to use multiple configuration files in webpack?

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?

Upvotes: 24

Views: 37749

Answers (4)

Carloluis
Carloluis

Reputation: 4320

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.

Upvotes: 26

jogarcia
jogarcia

Reputation: 2742

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"
},
...

Upvotes: 9

Zar Shardan
Zar Shardan

Reputation: 5921

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

Upvotes: 6

IvanM
IvanM

Reputation: 3053

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;

Upvotes: 2

Related Questions