webpack bits: Getting the most out of the CommonsChunkPlugin()
From time to time, the webpack core team loves to get the community involved on Twitter, and share bits and pieces of knowledge in a fun and informative way.
Summary
The webpack core team engaged with the community to optimize webpack configurations, focusing on reducing code duplication and improving caching strategies with the CommonsChunkPlugin.
Abstract
The webpack core team initiated a community-driven effort on Twitter to help developers optimize their webpack configurations. Participants were encouraged to use the webpack-bundle-analyzer to visualize their bundles and share them for feedback. The most common issue identified was code duplication across multiple bundles. The article highlights two case studies where the CommonsChunkPlugin was used effectively to address this by extracting common dependencies into separate vendor bundles and applying caching strategies. The first case involved multiple vendor bundles with duplicate code, which was improved by creating a meta-cache for common libraries. The second case dealt with duplicate vendors across async chunks, resolved by creating an async common chunk. Advanced techniques, such as using a minChunks function for more granular control, were also discussed. The article emphasizes that while the CommonsChunkPlugin is powerful, solutions should be tailored to the specific needs of the application, and developers should understand their build process before applying these optimizations.
Opinions
CommonsChunkPlugin effectively can lead to substantial reductions in overall application sizes and improvements in caching.minChunks property with a function allows for precise control over module extraction.CommonsChunkPlugin is a versatile tool, its implementation requires careful consideration and understanding of the application's specific requirements.From time to time, the webpack core team loves to get the community involved on Twitter, and share bits and pieces of knowledge in a fun and informative way.
This time, the “rules to the game” were simple. Install webpack-bundle-analyzer, generate a fancy colorful image of all of your bundles, and share it with me. In return, the webpack team offered to help identify any potential issues we could spot!
The most common theme was code duplication: Libraries, components, code was duplicated across multiple [sync or async] bundles!
Swizec Teller was kind enough to share one of his builds (which in fact is built for over 8–9 standalone single-page applications ). I chose this example out of all of them because there so many great techniques we can identify from it. So lets look at this in more detail:

We can infer quite a few things from this (without looking at the actual configuration).
Each single-page app is using a new CommonsChunkPlugin that targets just that entry point, and its vendor code. This creates a bundle with only modules that come from node_modules folder, and another bundle with just application code. The configuration portion was even provided:
Object.keys(activeApps)
.map(app => new webpack.optimize.CommonsChunkPlugin({
name: `${app}_vendor`,
chunks: [app],
minChunks: isVendor
}))The activeApps variable most likely represents each of the individual entry points.
Below are a few areas that I circled that could use some improvement.

What we see above is many large libraries like momentjs, lodash, and jquery being used across 6 or more vendor bundles. The strategy for adding all vendors into a separate bundle is good, but we should also apply that same strategy across all vendor bundles.
I suggested that Swizec add the following at the end of his plugins array:
new webpack.optimize.CommonsChunkPlugin({
children: true,
minChunks: 6
})What we are telling webpack is the following:
Hey webpack, look across all chunks (including the vendor ones that were generated) and move any modules that occur in at least 6 chunks to a separate file.
As you can see now, all of those modules were extracted into a separate file, and on top of that, Swizec reported that this decreased overall application sizes by 17%!
So this amount of duplication wasn’t as severe in terms of overall code size, however, when you look at the full size image below, you can see the exact same 3 modules across every async chunk.

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?
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:
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.
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!
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+.
CommonsChunkPlugin() may be powerful, but keep in mind that each one of these examples is tailored to the application it is applied to. So before you copy-pasta these snippets in, take advice from Sam Saccone and Paul Irish and MPDIA first to make sure you apply the right solution.


These are just a sampling of options and uses for CommonsChunkPlugin(). To find more, check out our /examples directory in our webpack/webpack core GitHub repo! If you have a great idea for more, feel free and submit a Pull Request!
No time to help contribute? Want to give back in other ways? Become a Backer or Sponsor to webpack by donating to our open collective. Open Collective not only helps support the Core Team, but also supports contributors who have spent significant time improving our organization on their free time! ❤
Alexander Nguyen1-page. Well-formatted.
Selcuk OzdemirIntroducing the ?= Operator: JavaScript’s New Error Handling Hero
Shuai LiMost interviewees failed on it.
Rosie HoggmascallEcho chambers, profit & the decline of artist discovery since 2017