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?

Author: Fantashit

10 thoughts on “Webpack 2.0 doesn’t support custom command line arguments?

  1. 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$/
            }))
      }
    }
  2. 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)

  3. @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.
  4. 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?

  5. 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
  6. @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
        }
      }
    }
    
  7. 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

Comments are closed.