New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Webpack 2: -p option does not set NODE_ENV to "production" in webpack config #2537
Comments
|
Why should you not use env-variables in the config? I have a webpack config, which changes according to NODE_ENV. It's awesome because it's in one file and
const webpack = require('webpack'),
path = require('path'),
fs = require('fs')
const SRC = path.resolve(__dirname, "src"),
NODE_MODULES = path.resolve(__dirname, "node_modules")
/* babel */
const babelSettings = JSON.parse(fs.readFileSync(".babelrc"))
const config = {
entry: [
'./src/index.js'
],
module: {
loaders: [
{
test: /\.jsx?$/,
include: SRC,
loader: "babel-loader",
query: babelSettings
},
{
test: [
/\.png$/,
/\.jpg$/
],
loader: "url-loader"
},
{
test: /\.css$/,
include: [
NODE_MODULES,
SRC
],
loader: 'style-loader!css-loader!postcss-loader',
}
]
},
resolve: {
root: SRC,
extensions: [
'',
'.js',
'.jsx'
]
},
output: {
path: path.resolve(__dirname, 'public', 'assets'),
publicPath: '/assets',
filename: 'bundle.js'
},
postcss: [
require('autoprefixer')
],
plugins: [
new webpack.DefinePlugin({
'process.env': {
'NODE_ENV': JSON.stringify(process.env.NODE_ENV)
}
}),
]
};
if (process.env.NODE_ENV === 'production') {
config.plugins.push(
new webpack.optimize.UglifyJsPlugin({
compress: {
screw_ie8: true
}
})
)
babelSettings.plugins.push("transform-react-inline-elements");
babelSettings.plugins.push("transform-react-constant-elements");
} else {
config.devtool = "#cheap-module-source-map"
config.devServer = {
contentBase: './public',
hot: true,
inline: true,
host: "0.0.0.0",
port: 2708
}
config.plugins.push(
new webpack.HotModuleReplacementPlugin()
);
}
module.exports = config I noticed too that for some reason the output of "webpack -p" is different than just running |
Personally, I am not quite getting what you mean by _package.json_ {
"name": "webpack_test",
"version": "1.0.0",
"description": "",
"main": "build/bundle.js",
"scripts": {
"build": "webpack",
"build:prod": "webpack -p",
},
"author": "Benjamin Baldivia",
"license": "ISC",
"devDependencies": {
"webpack": "^1.13.2"
}
} _webpack.config.js_ const webpack = require('webpack');
const prod = process.argv.indexOf('-p') !== -1;
const config = {
entry: './src/main.js',
output: {
path: 'build',
filename: 'bundle.js'
}
};
/*
This code was seperated from the config for multiple reasons.
Other conditional things can be added very simply.
Also, the check for config.plugins is so it is not dependent on the structure above.
*/
config.plugins = config.plugins||[];
if (prod) {
config.plugins.push(new webpack.DefinePlugin({
'process.env': {
'NODE_ENV': `"production"`
}
}));
} else {
config.plugins.push(new webpack.DefinePlugin({
'process.env': {
'NODE_ENV': `""`
}
}));
}
module.exports = config; _src/main.js_ if (process.env.NODE_ENV === 'production') {
module.exports = require('./prod.js')
} else {
module.exports = require('./dev.js')
} _src/dev.js_ console.log("I am in dev"); src/prod.js console.log("I am in production"); The key here is really only the npm run build
# OUTPUT
#> webpack_test@1.0.0 build C:\Users\Goblin\dev\webpack_test
#> webpack
#
#Hash: 133cddf132a8bd0ff743
#Version: webpack 1.13.2
#Time: 42ms
# Asset Size Chunks Chunk Names
#bundle.js 1.61 kB 0 [emitted] main
# [0] ./src/main.js 140 bytes {0} [built]
# [1] ./src/dev.js 29 bytes {0} [built] npm run build:prod
#OUTPUT
#> webpack_test@1.0.0 build:prod C:\Users\Goblin\dev\webpack_test
#> webpack -p
#Hash: e5112caeb4609ddc76a9
#Version: webpack 1.13.2
#Time: 79ms
# Asset Size Chunks Chunk Names
#bundle.js 283 bytes 0 [emitted] main
# [0] ./src/main.js 140 bytes {0} [built]
# [1] ./src/prod.js 38 bytes {0} [built]
#
#WARNING in bundle.js from UglifyJs
#Condition always true [./src/main.js:1,0]
#Dropping unreachable code [./src/main.js:4,0] This is much mode in-line with what I believe users expect when using the |
Agree, it's really confusing that is says this in the changelog:
and then I usually call webpack setting EDIT: here is an example of what I'm doing, webpack-dashboard has an issue and so it needs to be included only in development |
I agree this is an issue. I spent several hour on it before I found out what is causing my problems :( |
Agreed, this seems like a departure from previous behaviour? Migration guides could alert to this also. |
What's the extra optimisation that |
The key part for me was to understand that environment variables are not available in the webpack build process unless specified. That's why we need the following line from @fab1an's great example :
....which can be stated more clearly using the
|
`-p` does not set `NODE_ENV` in the build script, see webpack/webpack#2537
`-p` does not set `NODE_ENV` in the build script, see webpack/webpack#2537
is |
could this simply be implemented just by adding |
Currently I'm handling this issue with And then in module.exports = function(env) {
// return env-specific configuration
} I do agree the |
It seems that most people here thinks that Not all are running webpack for production via the CLI, but programmatically via node. Shouldnt |
as plugins. It is not mandatory, it just enables those plugins for you for convenience. Because of the DefinePlugin, Basically, what you want to do is |
I don't think it's even possible to have a regular command line flag like |
I'm pretty new to web development and man this is confusing. Shouldn't webpack's default behavior be to simply pass along the NODE_ENV environment variable to the build? using its own plugin this way: Maybe I'm missing something but what scenarios require you to not pass along the NODE_ENV variable to source files when using webpack? If that becomes the default behavior:
Anyways, this is what I'm currently doing to completely avoid the confusing // package.json
{
"scripts": {
"build:dev-server": "webpack-dev-server --inline --progress --colors",
"build:dev": "webpack --progress --colors",
"build:dist": "NODE_ENV=production webpack --optimize-minimize --progress --colors",
} // webpack.config.js
var webpack = require('webpack');
var path = require('path');
var CopyWebpackPlugin = require('copy-webpack-plugin');
var config = {
// ...
plugins: [
new webpack.EnvironmentPlugin(['NODE_ENV']),
],
};
if (process.env.NODE_ENV == 'production') {
config.plugins.push(
new CopyWebpackPlugin([{
from: 'src/templates/index_prod.html',
to: 'templates/index.html'
}])
);
} else {
// ...
config.devtool = 'inline-source-map';
config.plugins.push(
new CopyWebpackPlugin([{
from: 'src/templates/index_dev.html',
to: 'templates/index.html'
}]),
);
}
module.exports = config; |
In order, to determine if I am in development or production mode I use the following code in my webpack.config.js: // detect if webpack bundle is being processed in a production or development env
let isDevelopmentMode = !(require('yargs').argv.p || false); then I can use it like: plugins: [
new webpack.DefinePlugin({
__DEBUG__: JSON.stringify(isDevelopmentMode)
}),
] I hope it helps for someone looking for an alternative. |
I do the following: "build": "webpack --env production", and then in the webpack config: const path = require('path');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const BabiliPlugin = require('babili-webpack-plugin');
const plugins = [
new ExtractTextPlugin({
filename: './bundle.css',
allChunks: true,
}),
];
module.exports = function webpackStuff(env) {
if (env === 'production') plugins.push(new BabiliPlugin());
return { /* the rest of your config goes here */ };
}; Now I just do |
The second argument of your config function contains webpack calling options. This is undocumented feature, but might be useful, anyway. module.exports = (env = {}, args = {}) => {
console.log(args);
// E.g. args.bail and args.p are true for webpack -p --bail
...
}; |
Wanting |
I think the usual reason is that people specify different configs based on the NODE_ENV env var. So something like: filename: process.env.NODE_ENV === 'production'
? '[name]-[chunkhash].js'
: '[name].js', I do that as well, but I agree that it's a separate thing and it should be kept separate mentally. I just think people get confused when it says that |
I finally settled on the EnvironmentConfig's defaulting behavior as in:
This just sets the default NODE_ENV value if not already defined. If you also set it on the command line, as in Yes it's confusing to write |
As it says, That is a separate thing, which is managed by setting the environment variable ie $ NODE_ENV=production webpack |
The solution is simple: rename |
Why not using: "scripts": {
"build": "webpack --env development",
"build:production": "webpack --env production"
} And inside module.exports = env => ({
/* ... */
plugins: [
new webpack.DefinePlugin({
'process.env': {
NODE_ENV: JSON.stringify(env),
},
}),
],
/* ... */
})
|
Please clarify your documentation then. (Add an additional mark, stating that it does not set it for the config itself) https://webpack.js.org/guides/production/#cli-alternatives states that -p sets both flags. But in webpack 3.9.1 it still only sets this variable for packages run by webpack and not the webpack config itself. Why use it? See my repo: https://github.com/SamanthaAdrichem/webpack-3.9.1-splitted-config-angular/ i'm using it to load separate development and production configs -p now feels like a useless argument |
Technically, NODE_ENV is a system environment variable that Node.js exposes into running scripts. It is used by convention to determine dev-vs-prod behavior by server tools, build scripts, and client-side libraries. Contrary to expectations, process.env.NODE_ENV is not set to "production" within the build script webpack.config.js, see #2537. Thus, conditionals like process.env.NODE_ENV === 'production' ? '[name].[hash].bundle.js' : '[name].bundle.js' within webpack configurations do not work as expected. |
I've made a webpack plugin, |
What is the difference between |
@mittalyashu It's in
|
So. After testing this way best for me. Doc: https://webpack.js.org/guides/environment-variables/ package.json webpack.config.js
|
After 16 months the hackaton ended. They had finally found a way to set the environment in webpack. |
@EspenLarod hahahahahahaha. |
@EspenLarod @jefer94 So, are you ready to update your webpack.config.js according to the latest webpack4 rfc? OMG, it's a big project... |
This is now fixed in webpack 4. Setting mode: production or development also sets the proper NODE_ENV |
@TheLarkInn I keep getting this
even when I am setting up
|
@yordis From the warning:
It means: Also from @TheLarkInn comment, webpack sets NODE_ENV according to |
I sometimes use
Update: yes there is. 🎉 😄
Update 2: this is still bad, do this:This should make it so webpack leaves
|
Webpack doesn't handle Dev. vs Prod. well. So I just created a package called Environmentally to handle it. 👍 |
I originally tried to do a positive environment check: `if (process.env.NODE_ENV === 'development')` Because Webpack, however, `process.env.NODE_ENV` was coming up undefined. There's lots of chatter about this on SO and GitHub, but the couple of solutions I tried didn't work. See, for example, [Webpack 2: -p option does not set NODE_ENV to "production" in webpack config #2537](webpack/webpack#2537) Maybe this `NODE_ENV` issue is only a problem when you're *not* building for production? If not, I would imagine this issue affects ALL projects based on Boilerplate, since all of them use `process.env` in server/index.js. For now, I've made the environment check a negative— `if (process.env.NODE_ENV !== 'production')` so if the variable actually _is_ successfully set on production, react-a11y won't run.
Is that an upcoming feature or why isn't the variable set when I try to access it in the webpack config with process.env.NODE_ENV ? I use webpack ^2.1
Furthermore I recognized that when using -p option the UglifyJsPlugin is applied? Don't see that in the documentation anywhere.
The text was updated successfully, but these errors were encountered: