exposing process.env.NODE_ENV to webpack

in both webpack@3.x and webpack@2.x we config node env in package.json scripts

 "scripts":{
      "build":"export NODE_ENV=production&& webpack"
  }

and in webpack.configure.js we do

 plugins: [
    new webpack.DefinePlugin({
      'process.env': {
        'NODE_ENV': JSON.stringify(process.env.NODE_ENV),
      },
    }),

to have NODE_ENV exposed to webpack;

in webpack@4.x it seems that we still need to

mode : process.env.NODE_ENV === 'production' ? 'production': 'development'

but I was wondering if this mapping is even needed. To be specific, in source code,

options => options.mode || “production”

if we change it to options => options.mode || process.env.NODE_ENV || "production" , would it bring convenience to developers (as they don’t have to the mapping), or would it bring confusions?

actually, the name options.optimization.nodeEnv is quite obvious that it should be populated with process.env.NODE_ENV . why can’t webpack do it directly?

Author: Fantashit

2 thoughts on “exposing process.env.NODE_ENV to webpack

  1. I’m against having process.env.NODE_ENV in my build set to the current environment. That’s a completely different thing. Even more of you have build servers.

    As said in my previous comment, setting optimization.nodeEnv is the way to go.

  2. Here is my opinion on that topic. I’m in general against using environment variables to configure stuff. You may ask why. I think it’s a very sneaky/leaky way to pass values. They are like globals, but even worse. You can read them anywere and set them nearly anywere. Setting them is not even restricted to this process. They can be set on OS-level or in process in between, i. e. by the shell or CI server, task runner, any npm package imported somewere. Just anywere. Regarding reading them: Any npm module could use any env variable to change it’s behavior. I. e. a loader could change behavior because any env variable is set to something.

    In my opinion this could lead to weird “works for me (not)” behavior. Or it works locally but behaves differently on CI.


    Instead use the methods intended for value passing. For CLIs use arguments. For code: use arguments in function calls or constructors. Best avoid static/global values and explicitly pass values.

    That’s also how the webpack and webpack-cli is designed:

    • The CLI takes custom arguments via --env, which is passed to the webpack.config.js via argument (when exporting a function). You can see on the command line which values affect the process.
    • The configuration file explicitly uses this value to pass it to configuration options. By reading the configuration file you see the dependencies.
    • Loaders are only affected by the options passed to them. We even removed access to the webpack options from the loader API, because this pattern was violated by some loaders.

    TL;DR: Avoid env variables.

    PS: Some users prefer using env variable to affect the webpack.config.js. While I don’t recommend that, we not actively trying to prevent users from using that.

Comments are closed.