package.json:
{
"name": "test",
"version": "0.0.1",
"dependencies": {},
"devDependencies": {
"react": "0.12.2",
"webpack": "1.7.2"
}
}
main.js:
var React = require('react')
console.log(process.env.NODE_ENV)
webpack.config.js:
var webpack = require('webpack')
module.exports = {
entry: {
app: './main'
},
output: {
path: '_dist',
filename: 'out.js'
},
resolve: {
extensions: ['', '.js', '.json']
},
plugins: [
new webpack.DefinePlugin({
'process.env': {
'NODE_ENV': '"production"'
}
})
]
}
Place all these files into the same directory and then run:
npm install
rm -rf _dist && ./node_modules/.bin/webpack
Then inspect _dist/out.js
. You will see that process.env.NODE_ENV
has been successfully injeted to main.js
module (line 47
):
var React = __webpack_require__(1)
console.log(("production"))
But all entries of process.env.NODE_ENV
inside React modules remain intact, e.g. line 314
:
("production" !== process.env.NODE_ENV ? warning(
standardName == null,
'Unknown DOM property ' + name + '. Did you mean ' + standardName + '?'
) : null);
You can verify this by searching for ("production")
and process.env.NODE_ENV
. Changing definition to a flat one doesn’t help:
plugins: [
new webpack.DefinePlugin({
'process.env.NODE_ENV': '"production"'
})
]
However, when I add UglifyJSPlugin
, injection starts working as intended: UglifyJS prints a lot of Condition always false
messages, and there are no occurrences of NODE_ENV
inside the minified out.js
.
when you take a closer look to the react file you’ll notice that it looks like this:
webpack already replaces the top-most
if ("production" !== process.env.NODE_ENV)
withif (false)
and skips the block. So theprocess.env.NODE_ENV
in the block never gets executed (UglifyJs will remove it, dead code).The DefinePlugin just replaces occurrences of the given identifiers with the given expressions. After that, UglifyJS detects dead code blocks and removes them.
@jhnns, then I don’t understand why it didn’t replace the inner
process.env.NODE_ENV
expression, inside theif (false)
block (see @sokra‘s comment)…@skozin Webpack does all of its AST walking and transforming together on an AST, and it does so while performing static analysis, so if it recognizes that it can’t get into one side of an if, it won’t run any transforms in that part.
DefinePlugin
hooks into that transform/traversal so it won’t bother substituting stuff into theif(false){
side of theif
.@loganfsmyth, thanks! That’s a great feature 🙂