webpack-cli: NODE_ENV not set on process.env
Do you want to request a feature or report a bug?
Bug
What is the current behavior?
Currently, mode
only sets the value for NODE_ENV
in the DefinePlugin
but not changes the process.env.NODE_ENV
.
For example, Babel depends on this env variable and when used with webpack --mode=production
it will still run in development
mode.
If the current behavior is a bug, please provide the steps to reproduce.
Running webpack --silent --mode=production && echo $NODE_ENV
This will NOT print anything.
Run NODE_ENV=production && webpack --silent --mode=production && echo $NODE_ENV
This will print production
What is the expected behavior?
Running webpack --silent --mode=production && echo $NODE_ENV
should print production
About this issue
- Original URL
- State: closed
- Created 6 years ago
- Reactions: 29
- Comments: 35 (8 by maintainers)
Commits related to this issue
- risteys: use purgecss in production Makes the CSS file smaller as it removes all the non-used classes from Tailwind. Only enabled in production builds as it is optimization and extend the build proce... — committed to dsgelab/risteys by vincent-octo 5 years ago
- Explicitly set the node environment variable - Webpack does not set this, but the processes it calls (like tailwind) need it to be set. - See https://github.com/webpack/webpack/issues/7074 for a lo... — committed to andrewkfiedler/ace by andrewkfiedler 4 years ago
- Explicitly set the node environment variable (#100) - Webpack does not set this, but the processes it calls (like tailwind) need it to be set. - See https://github.com/webpack/webpack/issues/7074 f... — committed to connexta/ace by andrewkfiedler 4 years ago
- Use webpack node-env flag see https://github.com/webpack/webpack-cli/issues/2362#issuecomment-771776945 — committed to D3SOX/d3sox.github.io by D3SOX 3 years ago
I think this bit of information should be reflected in the documentation: https://webpack.js.org/concepts/mode/. As it reads now - “Provides process.env.NODE_ENV with value XXXXXX”, this lead me to believe that passing the mode as a CLI argument set process.env.NODE_ENV for the whole environment.
But honestly I think that there is a problem with the mental model here. If something called in relation to node
process.env
then themode
should set it to that value during compile time.The manual literally says:
And the docs for
sass-loader
includes an example using:I guess this will silently use
style-loader
sinceprocess.env.NODE_ENV
is alwaysundefined
?I was hoping to do something similar, so what’s the alternative?
How can I check which
--mode
is being run, so I can make variations in mywebpack.config.js
betweendevelopment
andproduction
modes?For future seekers, now we support
--node-env
, what is benefits:cross-env
package:Before:
Now (you can remove the
cross-env
if you don’t use it somewhere else):mode
option respect the--node-env
option if you don’t set themode
option explicit using CLI options or in configuration(s), i.e.--node-env production
setprocess.env.NODE_ENV
andmode
toproduction
I get the same result But I found that
console.log(process.env); // {}
console.log(process.env.NODE_ENV); // development
I was very surprised that
--mode=production
doesn’t setprocess.env.NODE_ENV
with valueproduction
withinwebpack.config.js
but only provides this variable for your bundles.So basically just a replacement for the old fashioned:
To others looking for a solution, I found it here: export a function instead of an object, and it will be called with parsed/normalized environment and argument objects.
(I’m submitting a PR for the
sass-loader
example, which doesn’t work.)Honestly, thanks a million @mindplay-dk, this was driving me nuts… I never realised there was an argv being passed in. Just to have it here:
This is an absolutely perfect example of why my love meter for “modern javascript” constantly veers back into the negative
I’d argue it should actually set the variable to allow related tools be executed in the right context.
babel-loader
doesn’t rely on it per-se but since the loader executesbabel-core
which relies on it, it might break things right now.Then the documentation is misleading and needs to be updated? It should probably explicitly say that it only does
new webpack.DefinePlugin({ "process.env.NODE_ENV": JSON.stringify("development") }),
&& echo $NODE_ENV
will showNODE_ENV
value after previous command finished successfully, webpack will change it only while it runs, it doesn’t change it for the entire system.I don’t know exactly at what point exactly webpack sets
process.env.NODE_ENV
, also don’t know if loaders should rely on it, by reading https://github.com/webpack/webpack/issues/2537#issuecomment-221024348 one could conclude that it doesn’t affect loaders source environment.So you still have to set it at command level, so I would affect entire execution context.
IMHO if “mode” is specified, no matter wether via command line or the configuration file, process.env.NODE_ENV should be set to that value, the behaviour should be as simple as that. I’ve spent days trying to understand why it wasn’t being set, and the behaviour of the “-p” flag is totally misleading 😕
@adamwathan I suggested it in my comment (which I incidentally wrote after I got the purge option to work with Tailwind!)
Nothing wrong with that. But using https://github.com/kentcdodds/cross-env instead seems to be a very popular (and safer) alternative, and is used by all kinds of projects.
Alternatively, I do it like this:
https://stackoverflow.com/questions/55259238/what-is-the-difference-between-webpack-env-production-and-mode-production
Basically --mode just sets “process.env.NODE_ENV” on DefinePlugin only. And you can access it inside function exported from your webpack.config.js.
–env also has nothing to do with process.env and it operates on object passed to your exported function.
One trick would be to assign process.env.NODE_ENV manually like this:
process.env.NODE_ENV will be correctly defined in other configs you use like postcss.config.js
or just use cross-env and if you want --mode functionality as well do this(for webpack to add it to DefinePlugin as well):
Note it won’t be available in
argv.mode
then if you don’t pass it with cmd linemy idea.
running
webpack
orNODE_ENV=development webpack
not set --mode option.
Best regards,
In package.json “scripts”: { “dev”: “webpack --mode development --watch”, “build”: “webpack --mode production”, }
In webpack.config.js module.exports = (env, options) => { const devMode = options.mode !== ‘production’; return { entry: … output: … module: { … { test: /.(sa|sc|c)ss$/, use: [ devMode ? “style-loader” : MiniCssExtractPlugin.loader, “css-loader”, “sass-loader” ] }, … } … } }
Thanks,it works
I haven’t seen anyone suggesting setting the variable for the script execution on the command line just like this:
Am I missing a reason this isn’t a good solution?
first try
second try
“scripts”: { “test”: “echo "Error: no test specified" && exit 1”, “dev”: “webpack --config ./conf/webpack.config.js --mode development”, “build”: "webpack --config ./conf/webpack.config.js --mode production " },
2 . webpack.config.js
add plugin parameter value into webpack config. module.exports = { entry: …, plugins: [ new webpack.DefinePlugin({ ‘process.env’: { ‘NODE_ENV’: ‘"’ + process.env.NODE_ENV + ‘"’ } }), ], output: {…} }
NODE_ENV=dev npm run dev or NODE_ENV=prod npm run build
It will set the environment as you pass on command line.