Tree Shaking, a modern dead code elimination algorithm for ECMAScript 2015+ is one of the most anticipated features in Webpack 2. By eliminating unused ES6 exports, Webpack can further help the minification process to get your bundle much smaller than ever before.

Update 11/14/2016: Webpack 2 sample application code has been updated to match the most recent updates in Webpack (v2.2), React (v15.4) and Babel.

Tree Shaking With WebPack 2

Tree shaking, ultimately, bundles only the modules you import into your scripts. Any exports that were not imported will not be in the final JavaScript build.

In the sample code below, I will show how my new Webpack 2 configuration helped cut 28% out of my already optimized Webpack 1 project.

CommonJS Out, Native Imports In

Webpack 2 now knows how to work out the imports natively, without having to convert them to CommonJS modules. This is very important because CommonJS exports leaves references alive, meaning everything you declared in exports will have to be included in your final build.

To cut a long story short, you need to slightly adjust your .babelrc configuration. Instead of es2015 preset, you’ll need a new one named ‘babel-preset-es2015-native-modules’. This preset tells Babel to skip CommonJS module conversion during the transpilation process.

You would install this preset with npm.

npm i babel-preset-es2015-native-modules --save-dev

Your new .babelrc will look like this:

{

“presets”: [“es2015-native-modules”]

}

Or, if you use React

{

“presets”: [“es2015-native-modules”, “react”]

}

Your Babel configuration is now ready. Essentially, this was all it takes for tree shaking to work in Webpack 2.

Now, let’s shift focus on some of the important updates in Webpack 2 configuration for those who want to convert from v1.x.

Migrating from Webpack 1 to Webpack 2

Tree shaking works out of the box in Webpack 2. If you have an existing project, chances are you will want to upgrade your old configuration. Alternatively, some of you might use seed projects that were meant to work with Webpack 1.x. Let’s review just a few of the breaking changes that will likely require you to update some of the settings.

Loaders configuration

There have been minor improvements in how you define loader configuration. The previous GET-like syntax has been replaced with JSON-style notation.

Let’s observe this Webpack 1.x example:

loaders: [{

test: /\.html$/,

loader: 'file?name=[name].[ext]'

}]

The Webpack 2.x version of the same would look like this:

loaders: [{

test: /\.html$/,

loader: 'file',

query: {

name: '[name].[ext]'

}

}]

Notice how query parameters are now neatly stacked as key-value pairs.

2. Resolvers

In Webpack 2, resolvers from `root`, `modulesDirectories`, and `fallback` settings will merge into a single property — `modules`. Here is how we can resolve file and module locations in Webpack 2:

resolve: {

modules: [

path.resolve('./client'),

'node_modules'

]

}

You can specify a number of directories in `modules`, but make sure not to forget `node_modules` or npm package dependencies will fail to load.

3. Uglify Plugin Changes

The UglifyJsPlugin will no longer put loaders into minimize mode, and the debug option has been deprecated. These options are simply moved into a new plugin, LoaderOptionsPlugin, for separation of concerns reasons. Use it as such:

new webpack.LoaderOptionsPlugin({

minimize: true,

debug: false

}),

4. Other changes

Tobias Koppers aka Sokra published a very useful What’s new in Webpack 2 gist, which I highly recommend looking at.

Working Example

Take a look at this sample React + Redux + Webpack 2 sample app that leverages all of the important configuration settings that will make your production build smaller than ever. Comparing to the original Webpack 1.x version of the same app, the size went down by a whopping 28%.

Take a look yourself and share this with your network. Someone will surely want to optimize their webpack build using the new tree shaking technology.

Project URL: https://github.com/ModusCreateOrg/budgeting-sample-app-webpack2