66

I have a simple webpack.config.js

module.exports = {
  entry: "./app.js",
  output: {
    filename: "bundle.js"
  },
}

And I want to pass the values for entryand output through command line arguments. Is that possible and how would I do that?

Oblomov
  • 7,935
  • 20
  • 55
  • 98

6 Answers6

58

webpack.config.js can also exports a function of env which can return a conf object. You can therefore have a webpack config like:

module.exports = env => {
    return {
        entry: env === "production" ? "./app.js": "app-dev.js",
        output: {
          filename: "bundle.js"
        },
    }
};

and then call webpack from command-line (or package.json) like this:

webpack --env=production
Axnyff
  • 8,235
  • 3
  • 31
  • 36
22

You can provide custom parameters by passing environment variables on the command line. The syntax for this has changed between version 4 and 5 of Webpack. For this example, you would call:

For Webpack 5:

webpack --env entry='./app.js' --env output='bundle.js'

For Webpack 4:

webpack --env.entry='./app.js' --env.output='bundle.js'

For both versions, you can then access the environment variables in your Webpack config by doing

module.exports = env => ({
  entry: env.entry,
  output: {
    filename: env.output
  },
});
adrian
  • 2,515
  • 1
  • 21
  • 25
  • 3
    It's not clear from your answer whether this `env` argument magical or we can pass arbitrary parameters, like `--paramName1=value --paramName2=value` – Mikhail Batcer Jan 09 '20 at 20:27
  • THIS DOESNT WORK !! webpack --env.entry='./app.js' --env.output='bundle.js' CORRECT IS webpack --env=mode=production --env=branch=develop – madruga Feb 12 '22 at 18:23
  • 2
    @madruga This worked for Webpack 4, which was the latest version when this answer was written. The syntax has now been changed for Webpack 5. More info here: webpack.js.org/guides/environment-variables. I've now updated my answer to reflect this. – adrian Feb 15 '22 at 16:10
18

You can also pass multiple key-value pairs to you config using --env=key=value:

webpack --env=mode=production --env=branch=develop

or (for development with webpack-dev-server):

webpack serve --env=mode=production --env=branch=develop

webpack.config.js would look like this:

module.exports = (env) => {
  const mode = env.mode === 'prod' ? 'dev';
  const branch = env.branch ? env.branch : 'develop';

  return {
    entry: mode === 'prod' ? './app.js': 'app-dev.js',
    output: {
      filename: 'bundle.js',
      path: 'dist/' + branch),
    },
  }
}

All values passed this way are available as an object in the config which makes it easy to use them.

{ 
  WEBPACK_BUNDLE: true,
  mode: 'production',
  branch: 'feature-x',
  foo: 'bar'
}
zeropaper
  • 546
  • 6
  • 20
Pateta
  • 350
  • 3
  • 14
7

You can use the --env CLI argument to pass arbitrary parameters to the config.

For example, the following command:

webpack --env entry=./entry.js --env output=./output.js

Will produce the following env object:

{entry: './entry.js', output: './output.js'}

Which you can then use in your config like so:

module.exports = env => ({
  entry: env.entry,
  output: {
    filename: env.output
  },
});

Read more here: Webpack - Environment Variables

Yoav Kadosh
  • 4,381
  • 4
  • 37
  • 56
  • The other answers in this thread have the wrong syntax and fail to explain how it can be used for arbitrary parameters. My answer covers both. – Yoav Kadosh Mar 14 '21 at 11:41
  • 1
    @user1934212 this answer is very clear and supports multiple variables, i'd mark it as correct. – chantey Jun 16 '21 at 01:48
3

You may use argv package and set the variables. You must do it before module.export.

PRAISER
  • 757
  • 7
  • 14
  • 1
    Thanks, I will definitely try that. But is there no easier way, without the need of an additional package reference? After all, webpack.config.js is just javascript code. – Oblomov May 22 '17 at 12:55
  • 2
    You can pass --env=test for instance through command line and then you can export a function of env which returns an instead of directly an object https://webpack.js.org/configuration/configuration-types/#exporting-a-function-to-use-env – Axnyff May 22 '17 at 12:58
  • You may read this then: http://justindavis.co/2014/11/24/using-command-line-arguments-in-a-node-script/ – PRAISER May 22 '17 at 12:58
  • Thanks @Axnyff: the env-trick seems to work for me. If you promote it to a complete answer, I can accept it. – Oblomov May 22 '17 at 13:14
  • I just did, is this still ok for you ? – Axnyff May 22 '17 at 13:24
  • @PRAISER Could you please elaborate on this – Mikhail Batcer Jan 09 '20 at 20:25
1

The easiest way, in my opinion, to pass arguments is to use Node. Webpack being the one receiving the arguments, you can save your command line arguments in a dedicated environment variable (which exists only within the session):

// webpack.config.js 
process.env.MY_APPLICATION_NAME_ARGS = JSON.stringify(process.argv)

export default {
...

Then in your main.js (anywhere where you want to parse them), you retrieve your command line arguments from your dedicated environment variable.

// main.js
const myArgs = JSON.parse(env.MY_APPLICATION_NAME_ARGS )

As you'll be retrieving all of the arguments you passed to Webpack, using this, you'll be able to use any node modules (like yargs for instance) painlessly to parse them (or do it manually of course).

So you'll be able to do things like these without any issues:

webpack ... --opt1 the_value --custom1 something
yarn run dev --opt1 the_value --custom1 something

etc.