Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Webpack 2.0 doesn't support custom command line arguments? #2254

Closed
hanfeisun opened this issue Mar 30, 2016 · 25 comments
Closed

Webpack 2.0 doesn't support custom command line arguments? #2254

hanfeisun opened this issue Mar 30, 2016 · 25 comments
Labels

Comments

@hanfeisun
Copy link

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?

@Strate
Copy link

Strate commented Mar 30, 2016

👍

@sokra
Copy link
Member

sokra commented Mar 30, 2016

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

@SimenB
Copy link
Contributor

SimenB commented Mar 31, 2016

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)

@sokra
Copy link
Member

sokra commented May 14, 2016

@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.

@budlight
Copy link

budlight commented Oct 5, 2016

👎

@luisherranz
Copy link

I'm in the same boat. I'd love to keep using yargs for my dynamic webpack configurations. What's the point in forbidding this? Avoiding typos?

@sokra
Copy link
Member

sokra commented Nov 18, 2016

What's the point in forbidding this?

see #2254 (comment)

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

@luisherranz
Copy link

We'll use that, thanks.

@chawk
Copy link

chawk commented Nov 26, 2016

The only way I have been able to pass arguments is using the below link.

https://www.hipstercode.com/blog/27/

@mnn
Copy link

mnn commented Nov 29, 2016

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
Copy link
Contributor

SimenB commented Nov 29, 2016

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

@mnn
Copy link

mnn commented Nov 29, 2016

"Solved" it by using classic yargs to get arguments prefixed with env.

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

And what about typo checking of custom args? 😆

@SpencerCarstens
Copy link

@mnn I am running into the same issue.

@joshfarrant
Copy link

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

@Pomax
Copy link

Pomax commented Feb 16, 2017

@joshfarrant and then where is the rest of the webpack config object, and how is it exported? Just console logging env.hello is not super useful.

@ghost
Copy link

ghost commented Feb 16, 2017

@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
    }
  }
}

@donnrriz
Copy link

donnrriz commented Jun 9, 2017

As I have used cross-env before that works for me (npm install cross-env)
for example when running a production build my package .json script is
"build": "cross-env NODE_ENV=production webpack -p"

and in webpack.config

process.env.NODE_ENV === 'production' ? this : that

@nealoke
Copy link

nealoke commented Jul 27, 2017

For people who have simply want args in their config file without the large if {} else{} statements, simply do like below. This simply returns an object.

module.exports = (env) => ({
    /* Your config */
});

@Pomax
Copy link

Pomax commented Jul 27, 2017

@nealoke this was already mentioned in #2254 (comment)

@SamanthaAdrichem
Copy link

So how do you get the env outside module.exports?

@Belouccio
Copy link

I have module.exports = function(env) { console.log(env);
I try all variants, for example --env='dev' and get undefined. why?

@SamanthaAdrichem
Copy link

SamanthaAdrichem commented Dec 14, 2017

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

@Belouccio
Copy link

Thank you! Now it works fine)

@phil123456
Copy link

phil123456 commented Oct 5, 2018

none of the above worked for me

npm run build --env.test='test'
npm run build --env.test=test
npm run build -- --env.test='test'
npm run build -- --env.test=test

process.env.test is always undefined
and env.test is never defined

@niko20
Copy link

niko20 commented Dec 4, 2018

Hello, Try
test='test' webpack --mode=development and in webpack config
module.exports = (env) => { console.log('test => ', process.env.test); }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests