javascriptwebpackbundlewebpack-plugincommonschunkplugin

Can someone explain Webpack's CommonsChunkPlugin


I get the general gist that the CommonsChunkPlugin looks at all the entry points, checks to see if there are common packages/dependencies between them and separates them into their own bundle.

So, let's assume I have the following configuration:

...
enrty : {
    entry1 : 'entry1.js', //which has 'jquery' as a dependency
    entry2 : 'entry2.js', //which has 'jquery as a dependency
    vendors : [
        'jquery',
        'some_jquery_plugin' //which has 'jquery' as a dependency
    ]
},
output: {
    path: PATHS.build,
    filename: '[name].bundle.js'
}
...

If I bundle without using CommonsChunkPlugin

I will end up with 3 new bundle files:

This is obviously bad because I will potentially load jquery 3 times in the page, so we don't want that.

If I bundle using CommonsChunkPlugin

Depending on what arguments I pass to CommonsChunkPlugin any of the following will happen:

What I do not understand/I am not sure I understand


Solution

  • This is how the CommonsChunkPlugin works.

    A common chunk "receives" the modules shared by several entry chunks. A good example of a complex configuration can be found in the Webpack repository.

    The CommonsChunkPlugin is run during the optimization phase of Webpack, which means that it operates in memory, just before the chunks are sealed and written to the disk.

    When several common chunks are defined, they are processed in order. In your case 3, it is like running the plugin twice. But please note that the CommonsChunkPlugin can have a more complex configuration (minSize, minChunks, etc) that impacts the way modules are moved.

    CASE 1:

    1. There are 3 entry chunks (entry1, entry2 and vendors).
    2. The configuration sets the commons chunk as a common chunk.
    3. The plugin processes the commons common chunk (since the chunk does not exist, it is created):
      1. It collects the modules that are used more than once in the other chunks: entry1, entry2 and vendors use jquery so the module is removed from these chunks and is added to the commons chunk.
      2. The commons chunk is flagged as an entry chunk while the entry1, entry2 and vendors chunks are unflagged as entry.
    4. Finally, since the commons chunk is an entry chunk it contains the runtime and the jquery module.

    CASE 2:

    1. There are 3 entry chunks (entry1, entry2 and vendors).
    2. The configuration sets the vendors chunk as a common chunk.
    3. The plugin processes the vendors common chunk:
      1. It collects the modules that are used more than once in the other chunks: entry1 and entry2 use jquery so the module is removed from these chunks (note that it is not added to the vendors chunk because the vendors chunk already contains it).
      2. The vendors chunk is flagged as an entry chunk while the entry1 and entry2 chunks are unflagged as entry.
    4. Finally, since the vendors chunk is an entry chunk, it contains the runtime and the jquery/jquery_plugin modules.

    CASE 3:

    1. There are 3 entry chunks (entry1, entry2 and vendors).
    2. The configuration sets the vendors chunk and the manifest chunk as common chunks.
    3. The plugin creates the manifest chunk as it does not exist.
    4. The plugin processes the vendors common chunk:
      1. It collects the modules that are used more than once in the other chunks: entry1 and entry2 use jquery so the module is removed from these chunks (note that it is not added to the vendors chunk because the vendors chunk already contains it).
      2. The vendors chunk is flagged as an entry chunk while the entry1 and entry2 chunks are unflagged as entry.
    5. The plugin processes the manifest common chunk (since the chunk does not exist, it is created):
      1. It collects the modules that are used more than once in the other chunks: as there are no modules used more than once, no module is moved.
      2. The manifest chunk is flagged as entry chunk while the entry1, entry2 and vendors are unflagged as entry.
    6. Finally, since the manifest chunk is an entry chunk it contains the runtime.