As you can see above, the same 2–3 components are used across all 40–50 async bundles. So how do we solve this with CommonsChunkPlugin?

Create an async Commons Chunk

The technique will be very similar to the first, however we will need to set the async property in the configuration option, to true as seen below:

new webpack.optimize.CommonsChunkPlugin({

async: true,

children: true,

filename: "commonlazy.js"

});

In the same way — webpack will scan all chunks and look for common modules. Since async: true , only code split bundles will be scanned. Because we did not specify minChunks the value defaults to 3. So what webpack is being told is:

Hey webpack, look through all normal [aka lazy loaded] chunks, and if you find the same module that appears across 3 or more chunks, then separate it out into a separate async commons chunk.

Here is what the result was:

There is likely room to even play with a larger minChunks value here to result in a smaller commonlazy.js bundle.

Now the async chunks are extremely tiny, and all of that code has been aggregated into one file called commonlazy.js . Since these bundle were already pretty tiny, the size impact wasn’t very noticeable until second visit. Now there is far less data being shipped per code split bundle and we are saving users load time and data consumption by placing those common modules into a separate cacheable chunk.

More control: minChunks function

So what if you want to have more control? There are scenarios where you don’t want to have a single shared bundle because not every lazy/entry chunk may use it. The minChunks property also takes a function!! This can be your “filtering predicate” for what modules are added to your newly created bundle. Below are examples of

new webpack.optimize.CommonsChunkPlugin({

filename: "lodash-moment-shared-bundle.js",

minChunks: function(module, count) {

return module.resource && /lodash|moment/.test(module.resource) && count >= 3

}

})

The example above says:

Yo webpack, when you come across a module whos absolute path matches lodash or momentjs, and occurs across 3 separate entries/chunks, then extract those modules into a separate bundle.

You could apply this same behavior to async bundles by setting `async: true` also!

Even moar control

With this minChunks you can create smaller subsets of cacheable vendors for specific entries and bundles. In the end, you may wind up with something that looks like this:

function lodashMomentModuleFilter(module, count) {

return module.resource && /lodash|moment/.test(module.resource) && count >= 2;

} function immutableReactModuleFilter(module, count) {

return module.resource && /immutable|react/.test(module.resource) && count >=4

} new webpack.optimize.CommonsChunkPlugin({

filename: "lodash-moment-shared-bundle.js",

minChunks: lodashMomentModuleFilter

}) new webpack.optimize.CommonsChunkPlugin({

filename: "immutable-react-shared-bundle.js",

minChunks: immutableReactModuleFilter

})

EDIT (April 1st): I stated that you could use filename with minChunks, but we prevent this now as of webpack 2.3.2+.

There is no silver bullet!