53

How can I get the current --mode specified in package.json inside webpack.config.js? (For instance, for pushing some plugins.)

package.json

"scripts": {
  "dev": "webpack --mode development",
  "build": "webpack --mode production"
}

What I did in Webpack 3:

package.json

"scripts": {
    "build": "cross-env NODE_ENV=development webpack",
    "prod": "cross-env NODE_ENV=production webpack"
  },

Then, I was able to get environment in Webpack with process.env.NODE_ENV.

Of course, I can pass NODE_ENV with --mode but I prefer to avoid duplication.

Fernando Espinosa
  • 4,625
  • 1
  • 30
  • 37
xAoc
  • 3,448
  • 3
  • 23
  • 36

4 Answers4

93

You want to avoid duplication of options passed on the script.

When you export a function, the function will be invoked with 2 arguments: an environment env as the first parameter and an options map argv as the second parameter.

package.json

"scripts": {
  "build-dev": "webpack --mode development",
  "build-prod": "webpack --mode production"
},

webpack.config.js

module.exports = (env, argv) => {
    console.log(`This is the Webpack 4 'mode': ${argv.mode}`);
    return {
        ...
    };
}

These are the results:

For npm run build-dev:

> webpack --mode development

This is the Webpack 4 'mode': development
Hash: 554dd20dff08600ad09b
Version: webpack 4.1.1
Time: 42ms
Built at: 2018-3-14 11:27:35

For npm run build-prod:

> webpack --mode production

This is the Webpack 4 'mode': production
Hash: 8cc6c4e6b736eaa4183e
Version: webpack 4.1.1
Time: 42ms
Built at: 2018-3-14 11:28:32
Fernando Espinosa
  • 4,625
  • 1
  • 30
  • 37
15

To test if is in production mode, inside webpack.config.js file I use this:

const isProduction = process.argv[process.argv.indexOf('--mode') + 1] === 'production';

const config = {
    ...
};

if (isProduction) {
    config.plugins.push(new MiniCssExtractPlugin());
} else { // isDev
    config.devtool = /*'source-map'*/  'inline-source-map';
}

module.exports = config;

Stop trying NODE_ENV, is old school ( webpack 3 ).

And this is more compatible to work with import / webpack resolver

Daniel De León
  • 13,196
  • 5
  • 87
  • 72
3

Try this one

package.json

"scripts": {
  "dev": "webpack --mode development",
  "build": "webpack --mode production --env.production"
}

so if you are using the env inside webpack config, that looks something like this

module.exports = env => {
     const inProduction = env.production
     return  {
        entry: {...},
        output: {...},
        module: {...}
     }
}

more details to set up your webpack.config.js. (Environment Variables for webpack 4)

Macuvex
  • 47
  • 2
1

I ended up (ab)using npm_lifecycle_script to set the mode in the DefinePlugin:

MODE: JSON.stringify(process.env.npm_lifecycle_script.substr(process.env.npm_lifecycle_script.indexOf('--mode ') + '--mode '.length, process.env.npm_lifecycle_script.substr(process.env.npm_lifecycle_script.indexOf('--mode ') + '--mode '.length).search(/($|\s)/)))

This takes the value of the --mode parameter from the issued webpack command.

BillyNate
  • 908
  • 5
  • 10
  • Yes, I also use `process.env.npm_lifecycle_script` to define `--production`, `--development` and `--watch` in the webpack command in npm to add different things to webpack configuration depending on it (babel loader only for production and browser sync plugin only for the start script with watch), but I really don't know whether it's a good practice. – Roman Karagodin Apr 17 '22 at 09:28