If you’ve been developing with React, you must have seen that you are provided with very verbose errors/warnings that can come in handy.
Quote from the download page of React:
We provide two versions of React: an uncompressed version for development and a minified version for production. The development version includes extra warnings about common mistakes, whereas the production version includes extra performance optimizations and strips all error messages.
When you’re making your production bundle, you should not include all the extra code used in development (which makes extra checks not useful in production and at the end makes your bundle heavy).
The way to do that is to use the Webpack.DefinePlugin or envify, if you’re using browserify.
By doing the following, you’ll be injecting a variable process.env.NODE_ENV
set to "production"
at build time which is used inside React as we’ll see.
webpack.config.prod.js
module.exports = {
//...
plugins:[
new webpack.DefinePlugin({
'process.env':{
'NODE_ENV': JSON.stringify('production')
}
}),
new webpack.optimize.UglifyJsPlugin({
compress:{
warnings: true
}
})
]
//...
}
That way, you’ll be including the same kind of code which is in react.min.js
inside your bundle. If you take a look at the source code of React inside ./node_modules/react/lib
, you’ll see a lot of places with a ternary like process.env.NODE_ENV !== 'production'
. All those development related features will be dropped at the minification step.
Resources:
- Optimize your bundle’s weight with webpack
- React – recommendation of use
- Example of webpack.config.js on topheman/react-es6-redux
Notes:
But why not directly use the production version react.min.js
published by facebook ?…
That way, you get to keep using the development version (with the extra checking/errors/warnings) while you’re developping.
Yeah but it takes time to minify, I could simply use the resolve.alias
property of webpack and alias react
to react.min.js
wherever I use it in the code …
You could do that, it would totally work, but think about how UglifyJS works. Since its algorithm will be applied to your whole app, similarities might be found (like document
which is used in React and probably other modules). I’ll agree that since it’s developed in a modular way, it won’t find so much of those …
However, you’ll still be minifying an alredy minified file … You may be able to skip minification for some files but this adds complexity …
Why do you use JSON.stringify(‘production’)? Do we get any extra benefit from it? can’t we just use like below
new webpack.DefinePlugin({
‘process.env’:{
‘NODE_ENV’: ‘production’
}
}),
@nmrony – the value needs to be “‘production'” (i.e. a quoted strong), and not simply a string. JSON.stringify is a verbose way to do this to make it obvious what’s going on.
Thanks for the tip! 🙂
You can also use the EnvironmentPlugin of Webpack. That allows you to get rid of the weird JSON.stringify() call.
@Thibault You’re right about the EnvironmentPlugin. But some times you’ll want to use DefinePlugin because you need to preprocess those variables (like to set a default one or anything else), here is a use case: https://github.com/topheman/webpack-babel-starter/blob/master/webpack.config.js#L28-L32
Thanks a lot for your article. Things worked like a charm 🙂 Kudos to you…
I do not even know how I ended up here, however I believed
this submit was good. I don’t realize who you might be but certainly you’re going to a famous
blogger when you are not already. Cheers!