Optimize React size and performance with Webpack production plugins

In notebook:
Egghead Webpack
Created at:
2016-06-20
Updated:
2016-06-20
Tags:
JavaScript Webpack libraries Performance React
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
            }
        }))
    ])
}