Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I use NODE_ENV="staging" with mode="production" in webpack 4?

My app use NODE_ENV for deciding which api server should request to.

NODE_ENV="production" => https://api.***/
NODE_ENV="staging" => https://api.staging-***/
NODE_ENV="development" => http://localhost:3000/

I want to build staging bundle with mode="production" but keep NODE_ENV="staging".

I try to build with config below, but bundle.js becomes NODE_ENV="production".

{
   mode: "production",
   plugins: [
     new webpack.DefinePlugin({
       'process.env': {
         'NODE_ENV': JSON.stringify("staging")
       }
     })
   ]
 }
like image 723
Fumiya Karasawa Avatar asked Feb 27 '18 03:02

Fumiya Karasawa


People also ask

What is NODE_ENV used for?

NODE_ENV is an environment variable that stands for node environment in express server. The NODE_ENV environment variable specifies the environment in which an application is running (usually, development or production).

How do I change the production mode on Webpack?

Set 'mode' option to 'development' or 'production' to enable defaults for this environment. We can get around this by passing --mode production in the cmdline like below: npm run webpack --mode development ... As is mentioned on the webpack documentation, blog and everywhere else on the internet.

What is the purpose of NODE_ENV Why do we even need the different environments like production and staging?

NODE_ENV is used by many frameworks and packages like react-dom to optimize JavaScript build output, among other things. NODE_ENV is expected to be development for local development environments and production for deployed application environments.


2 Answers

I think that you want your staging build to be optimized just like your production build. And as far as I know some libraries (like React) will check if NODE_ENV === "production" to drop some error handling or provide further optimizations. So if you set NODE_ENV to staging they will "think" it's a development environment.

In this case, what I would do is just use a different variable like:

package.json

"scripts": {
  "dev": "webpack-dev-server --config webpack.config.js --env.TARGET_ENV=development",
  "staging": "webpack --config webpack.config.js --env.TARGET_ENV=staging",
  "production": "webpack --config webpack.config.js --env.TARGET_ENV=production"
},

webpack.config.js

module.exports = (env) => {
  const mode = env.TARGET_ENV === 'development' ? 'development' : 'production';

  return {
    mode: mode,
    plugins: [
      new webpack.DefinePlugin({
        'process.env': {
          'TARGET_ENV': JSON.stringify(env.TARGET_ENV)
        }
      })
    ]
    // ...rest of config based on environment
  };
};
like image 158
Tomasz Mularczyk Avatar answered Sep 28 '22 09:09

Tomasz Mularczyk


Webpack-cli is being deprecated and the syntax with env won't work anymore with Webpack-command (https://github.com/webpack-contrib/webpack-command#the---env-flag-is-nuked).

To satisfy your requirement I would use a simple env variable and use it the standard node way

var API_URL = {
  production: JSON.stringify('https://foo.bar/api'),
  development: JSON.stringify('http://localhost:3000/api'),
  staging: JSON.stringify('http://foo.stage.bar/api')
}

module.exports = function(argv) {
  const TARGET = process.env.TARGET_ENV ? process.env.TARGET_ENV : 'development';
  return {
    mode: argv.mode ? argv.mode : 'development',
....
    new webpack.DefinePlugin({
        'API_URL': API_URL[TARGET]
    }),
....
}

and call webpack like this:

TARGET_ENV=staging webpack 

In this way you would find your env variable API_URL defined globally in the app.

I would avoid redefining NODE_ENV through the define plugin.

like image 35
sickrandir Avatar answered Sep 28 '22 09:09

sickrandir