webpack: Webpack 2.0 doesn't support custom command line arguments?

In Webpack 1.x, I can pass in my own command line arguments like this:

webpack --config ./webpack.config.prod.js --compress true

Here --compress is the custom command line arguments, it can be used like this in the webpack.config.js:

var argv = require('yargs').argv;

if (argv.compress === 'true') {
    var CompressionPlugin = require('compression-webpack-plugin');
    config.plugins.push(
        new CompressionPlugin({
            asset: '{file}',
            algorithm: 'gzip',
            regExp: /\.js$|\.html$/
        }))
}

However, in Webpack 2.0, this approach doesn’t work any more. When I type in webpack --config ./webpack.config.prod.js --compress true. The webpack will just throw an error:

Unknown argument: compress And then stops… Would there be a way in Webpack 2.0 to support custom command line arguments?

About this issue

  • Original URL
  • State: closed
  • Created 8 years ago
  • Reactions: 16
  • Comments: 25 (5 by maintainers)

Commits related to this issue

Most upvoted comments

Yes this is intended. Custom argumens can be passed via --env prefix, i. e. --env.compress. Than export a function from the webpack.config.js and it’s called with the env parameter.

module.exports = function(env) {
  // ...
  if (env.compress === 'true') {
    var CompressionPlugin = require('compression-webpack-plugin');
    config.plugins.push(
        new CompressionPlugin({
            asset: '{file}',
            algorithm: 'gzip',
            regExp: /\.js$|\.html$/
        }))
  }
}

I still think the advantage of allowing custom args is bigger than the advantage of typo checking

👎

If anyone else comes here searching for the answer, I solved it as follows:

// webpack.config.js
module.exports = function(env) {
  console.log(env.hello); // 'world'
}
npm run build -- --env.hello world

What’s the point in forbidding this?

see https://github.com/webpack/webpack/issues/2254#issuecomment-219219418

You can still pass arguments. Just prefix --env.: i. e. --env.magic=5.

@Pomax – you just have to return the config > webpack --env.prod

module.exports = function(env) {
  if( env.prod ) {
    return {
      .... prod config 
    }
  } else {
    return {
      ... dev config
    }
  }
}

You can still pass arguments. Just prefix --env.: i. e. --env.magic=5.

This isn’t working for me.

...
module.exports = function makeWebpackConfig(cfgEnv) {
...
  console.log('env is ', cfgEnv);
...
}
$ ./node_modules/.bin/webpack --env.a=1
env is  undefined
$ ./node_modules/.bin/webpack --env.a 1
env is  undefined
$ ./node_modules/.bin/webpack -v
2.1.0-beta.26

Am I doing something wrong?

@SimenB Look like in your case a custom CLI tool for the build is more suitable. You basically build one. You can just move the CLI stuff from the webpack.config.js into a build.js and start webpack from this file (by using the node.js API).

There were a couple of reasons why I decided to disallow custom arguments:

  • webpack can error when passing incorrect or deprecated CLI arguments. This should help users when using the CLI.
  • webpack.config.js is a “pure” module. input -> output. It should not read stuff from the enviroment.
  • New tools can emerge which can use the webpack.config.js. Examples:
    • Split the build process into multiple processes, each calling the webpack.config.js. This would not work if the webpack.config.js reads the arguments.
    • Build combinations which call the webpack.config.js which different combinations of options. A standard format of passing arguments to the webpack.config.js helps a lot here.
    • etc.

I just rewrote the build at work, and added yargs into webpack.config.js, and this works great (still using webpack 1). Especially demanding args is nice, but also printing usage message etc…

We have a quite complex build capable of building 5 different webapps, proxying different backends, and different versions of production to build for, and being able to use yargs at the top level for this is perfect, as we also use webpack-config.

I know I can get (mostly) the same out of using the env-flag, but some things are missing, such as demanding, defaults (which is really nice), choices (even nicer) and usage printing. So it’s more limiting; I have to manually check that usage is correct, I have to manually set defaults, check if value is valid, that it’s passed a string or boolean, etc. All of these things I got declaratively from using yargs in webpack 1, while in webpack 2 I have to do it manually.

I understand that in most cases, using env is enough, but in our case, it’s actually not, without lot’s of boilerplate code added. Just removing strict, like in my PR, would solve this. And maybe try to flag somewhere very visible that env is available. (I read it in your release notes, so I knew about it, but I can’t see it in the README, for instance)

i believe your syntax should be --env.development

but really, whats better is doing the following: NODE_ENV=development; webpack …

we have the following npm run script in package.json using cross-env so that it also works on windows.

"production:build": "cross-env NODE_ENV=production webpack -p --progress --colors"

then in the code:

export const APP_ENV = process.env.NODE_ENV === 'production'
	? 'production'
	: 'development';

and use APP_ENV everywhere else

full example: https://github.com/SamanthaAdrichem/webpack-3.9.1-splitted-config-angular