Optimize React size and performance with Webpack production plugins
In package.json you can add
-p
flag for the build
task to enable a bunch of optimisation options. (“build:prod”: “webpack —-env.prod -p”
)Or just in the command line:
$webpack —-env.prod -p
It will remove a lot of dead code, unreachable code, uglifies, etc. In the example it reduces the size from 832kB to 165kB.
Fine tune optimisations
First, need to remove
-p
to avoid double-minification. To use Webpack plugins we need to require webpack in the webpack.config.js file. (
const webpack = require('webpack')
).
// **** webpack.config.js ****
// 1. ++++
const webpack = require('webpack')
const {resolve} = require('path')
module.exports = env => {
// 2. ++++ plugin helpers
const addPlugin = (add, plugin) => add ? plugin : undefined
// only use these plugins for the production build
const ifProd = plugin => addPlugin(env.prod, plugin)
// remove undefined plugis, see previous two notes
const removeEmpty = array => array.filter(i => !!i)
return {
entry: './js/app.js',
output: {
filename: 'bundle.js',
path: resolve(__dirname, 'dist'),
pathinfo: !env.prod
},
context: resolve(__dirname, 'src'),
devtool: env.prod ? 'source-map' : 'eval',
bail: env.prod,
module: {
loaders: [
{test: /\.js$/, loader: 'babel!eslint', exlcude: /node_modules/},
{test: /\.css$/, loader: 'style!css'}
]
}
},
// 3. ++++ define the plugins
// use the removeEmpty (see above) to remove undefined plugins in tests
plugins: removeEmpty([
// deduplicates imported modules
ifProd(new webpack.optimize.DedupePlugin()),
ifProd(new webpack.LoaderOptionsPlugin({
minimze: true,
// so far we it's the same as the -p options,
// we add more options
// NOTE: this plugin is only available in Webpack 2
debug: false
})),
ifProd(new webpack.DefinePlugin({
// wherever we use in our code:
// process.env.NODE_ENV === 'production'
// anywhere (if statement) it's not true
// it can be removed as dead code by uglify
// saves a lot of space with React
'process.env': {
NODE_ENV: '"production"'
}
})),
// finally add uglify
ifProd(new webpack.optimize.UglifyJsPlugin({
compress: {
screw_ie8: true, // eslint-disable-line
// above, we're controlling linter to not to ouput an error line
warning: false // less warnings in console
}
}))
])
}