9

I am using webpack in a Typescript project. I am following a tutorial where I have created 3 webpack files:

  1. webpack.common.js
  2. webpack.production.js
  3. webpack.development.js

Within the tutorial's package.json the "scripts" seconds have the following:

"build": "webpack --config webpack.$NODE_ENV.js"

I have been looking into the following SE Query to set the NODE_ENV for Windows 10.

Where within PowerShell I perform:

$env:NODE_ENV="development"

However once I execute npm run build the script still takes $NODE_ENV as a string and does not substitute the values.

I might shift to cross-env later if this doesn't work for me but I would like to give environments variables a try in the PowerShell.

What should be the equivalent commands for:

NODE_ENV=development npm run build
NODE_ENV=production npm run build

in windows and how should I change the scripts in my package.json viz. $NODE_ENV to accept the variables?

Using cross-env

It is possible to achieve something similar using cross-env by doing the following:

  1. npm i --save-dev cross-env
  2. Within "scripts" add:

     "build-dev": "cross-env NODE_ENV=development webpack --config webpack.%NODE_ENV%.js"
     "build-prod": "cross-env NODE_ENV=production webpack --config webpack.%NODE_ENV%.js"
    

    And this should trigger the respective scripts.

however, this still does not provide flexibility for user to run a generic npm script command whilst setting the env. variable on the fly

PowerShell Limitations

There are examples where queries suggest doing something of the likes of:

  set NODE_ENV=production&& npm run build

but this fails in PowerShell with the following error:

At line:1 char:24
+ set NODE_ENV=production&& npm run build-dev
+                        ~~
The token '&&' is not a valid statement separator in this version.
    + CategoryInfo          : ParserError: (:) [], ParentContainsErrorRecordException
    + FullyQualifiedErrorId : InvalidEndOfLine

And & is reserved for future-use.

Shan-Desai
  • 3,101
  • 3
  • 46
  • 89
  • 1
    You could have 3 separate build commands like: `build-common` `build-dev` and `build-prod` and set env there itself, example: `"build-dev": "set NODE_ENV=production&&webpack --config webpack.development.js"` – ambianBeing Aug 21 '19 at 10:31
  • @ambianBeing but doesn't this defeat the purpose of selecting the file based on environment variable set? – Shan-Desai Aug 21 '19 at 11:12
  • I know that's not exactly what you asked. But that's a cleaner way to do it. Otherwise I would've suggested write conditional statements in the `build` script but that's not pretty. Changing webpack config can achieve that as well I think but why. – ambianBeing Aug 21 '19 at 11:45

2 Answers2

5

I was able to Solve this issue based on comment from @ambienBeing. However here are some Caveats:

  • The && DOES NOT work in the PowerShell but WORKS in cmd
  • Instead of $NODE_ENV I needed to adapted %NODE_ENV% in the "scripts" part

    "build": "echo %NODE_ENV% && webpack --config webpack.%NODE_ENV%.js"
    

Upon executing the following:

 set NODE_ENV=production&&npm run build

the script gets executed correctly.

In order to be sure, I added console.log("production") as well as console.log("development") in the respective webpack.x.js files

and I could see the respective string printed in the console twice: 1 x from echo and 1 x from the file

Tests

  • This works perfectly well with VS Code when one changes the default shell to cmd instead of PowerShell
Shan-Desai
  • 3,101
  • 3
  • 46
  • 89
1

Change your package.json like the below:

Note you have to change all webpack.common.js, webpack.production.js, webpack.development.js

 webpack.common.js:

"build": "set NODE_ENV=development && webpack --config webpack.common.js"


 webpack.production.js:

"build": "set NODE_ENV=production && webpack --config webpack.production.js"


 webpack.development.js:

"build": "set NODE_ENV=development && webpack --config webpack.development.js"
GRS
  • 1,829
  • 1
  • 9
  • 23
  • It doesn't work. It still takes the `$NODE_ENV` as a string and does not substitute it – Shan-Desai Aug 21 '19 at 10:50
  • Edited the answer please check. You will have to do that change in three different files – GRS Aug 21 '19 at 10:54
  • I am not accessing them at the moment. I am just trying to use the Webpack HMR (Hot Module Reload) to work for a simple hello world – Shan-Desai Aug 21 '19 at 10:54
  • If you change all the three webpack configs it should work – GRS Aug 21 '19 at 10:55
  • In this case how will I know which environment will be set if the script is all named `build`? – Shan-Desai Aug 21 '19 at 10:59
  • In you rpackage.json -> scripts - "build": "set NODE_ENV=production && your_build_command" - by this way when you run "npm run build" it will pick up the correct environment. This is how its normally done – GRS Aug 21 '19 at 11:01