If you have a multi-page application (as opposed to a single page app), you’re likely sharing modules between these pages. By chunking these common modules into a single common bundle, you can leverage the browser cache much more powerfully. In this lesson we’ll use webpack’s CommonsChunkPlugin to easily share common modules between apps.
Here you'll see we have two applications being bundled by WebPack. The first is our todo app. The second is this AnimalFAX app. These two applications both use the helpers module. This is the animalfaxout.js file that uses a couple of the methods from the helpers module and this is the todo MVC app that also uses a couple methods from the helpers module.
Consequently, each bundle uses all of the code for the helpers module, and instead we'd like to split this helpers module into its own file so the browser only has to load and cache the code once for our entire application, rather than once for each page of our application.
For a small app like this that only shares a single module this isn't really a huge win, but as the applications grows this can make a real improvement in the performance of our application at load time.
To do this we're going to use the CommonsChunk plugin that comes with WebPack. Let's go ahead and jump into our WebPack config, and we'll require WebPack here. Now we can scroll down here, and right after module add plugins as an array, and we'll add a new webpack.ultimize.commonschunkplugin.
This will take an object where we can specify a couple of properties. We'll specify the name as common and the filename as bundle.common.js. This is literally all we have to do to make WebPack chunk our common modules together in a single file.
Now if we run the build, we'll see that WebPack manages everything for us, and we get a nice bundle.common.js file here, and that holds our helpers module. Then we have our other entries that we've specified in our WebPack config as well.
Unfortunately, we're not totally done. If we restart our server, then we're going to see that our applications are totally broken. The problem is that we get error, "webpackJsonp is not defined" in our console.
We still need to add this file as a script to the index HTML of both of the pages that reference it. So, we'll go ahead and do that here, and here.
Now if we restart our server, we'll see that both applications are now running just fine, and they're loading the same common file that we can see in our network tab, this bundle.com.js. We're taking full advantage of the browser cache for these common modules.
I wish I could say we're done, but there's still one more thing left to do. If we run our test, we're going to get that same error that we had before with the webpackJsonp is not defined. For the test we don't really care that the CommonsChunk plugin is used, so we're going to conditionally use this plugin by determining whether we're in a test environment.
If we open up our WebPack config, we'll see that it's a function that accepts an environment object that has properties on it that we can use to know what our environment currently is, and if we open up our common config where we get the WebPack configuration its passing test is true. So, we can simply conditionally load this plugin based off of ENV.test.
We can say ENV.test. If we're in test, then this will be undefined, otherwise we'll specify a new WebPack plugin, and because undefined plugins are not valid we'll have to call filter the plugins that are actually defined.
Now if we run our test again, we'll see that they pass just as they did before. It's notable that if you wish to combine this with an explicit vendor trunk strategy, you can add another CommonsChunk plugin to this plugins array with the configuration for the vendor chunk.
You'll likely be required to explicitly list the entries to use in the CommonsChunk, though. You can do this by adding a chunks property with an array of the entry names to have this plugin apply to.
In review, to chunk common files together you simply add the CommonsChunk plugin and specific a name and a filename for the chunk. Then update your index HTML files for each of your apps to utilize the new file.
Finally, you have to exclude the plugin in a test environment. That's how you chunk your common modules into a single bundled file to take full advantage of the browser cache for those modules.