Can someone explain Webpack's CommonsChunkPlugin
<p>I get the general gist that the <code>CommonsChunkPlugin</code> looks at all the entry points, checks to see if there are common packages/dependencies between them and separates them into their own bundle.</p>

<p>So, let's assume I have the following configuration:</p>

<pre><code>...
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'
}
...
</code></pre>

<h2>If I bundle without using <code>CommonsChunkPlugin</code></h2>

<p>I will end up with 3 new bundle files:</p>

<ul>
<li><code>entry1.bundle.js</code> which contains the complete code from <code>entry1.js</code> and <code>jquery</code> and contains its own runtime</li>
<li><code>entry2.bundle.js</code> which contains the complete code from <code>entry2.js</code> and <code>jquery</code> and contains its own runtime</li>
<li><code>vendors.bundle.js</code> which contains the complete code from <code>jquery</code> and <code>some_jquery_plugin</code> and contains its own runtime</li>
</ul>

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

<h2>If I bundle using <code>CommonsChunkPlugin</code></h2>

<p>Depending on what arguments I pass to <code>CommonsChunkPlugin</code> any of the following will happen:</p>

<ul>
<li><p><strong>CASE 1 :</strong> If I pass <code>{ name : 'commons' }</code> I will end up with the following bundle files:</p>

<ul>
<li><code>entry1.bundle.js</code> which contains the complete code from <code>entry1.js</code>, a requirement for <code>jquery</code> and does not contain the runtime</li>
<li><code>entry2.bundle.js</code> which contains the complete code from <code>entry2.js</code>, a requirement for <code>jquery</code> and does not contain the runtime</li>
<li><code>vendors.bundle.js</code> which contains the complete code from <code>some_jquery_plugin</code>, a requirement for <code>jquery</code> and does not contain the runtime</li>
<li><code>commons.bundle.js</code> which contains the complete code from <code>jquery</code> and contains the runtime</li>
</ul>

<p>This way we end up with some smaller bundles overall and the runtime is contained in the <code>commons</code> bundle. Pretty ok but not ideal.</p></li>
<li><p><strong>CASE 2 :</strong> If I pass <code>{ name : 'vendors' }</code> I will end up with the following bundle files:</p>

<ul>
<li><code>entry1.bundle.js</code> which contains the complete code from <code>entry1.js</code>, a requirement for <code>jquery</code> and does not contain the runtime</li>
<li><code>entry2.bundle.js</code> which contains the complete code from <code>entry2.js</code>, a requirement for <code>jquery</code> and does not contain the runtime</li>
<li><code>vendors.bundle.js</code> which contains the complete code from <code>jquery</code> and <code>some_jquery_plugin</code> and contains the runtime. </li>
</ul>

<p>This way, again, we end up with some smaller bundles overall but the runtime is now contained in the <code>vendors</code> bundle. It's a little worse than the previous case, since the runtime is now in the <code>vendors</code> bundle.</p></li>
<li><p><strong>CASE 3 :</strong> If I pass <code>{ names : ['vendors', 'manifest'] }</code> I will end up with the following bundle files:</p>

<ul>
<li><code>entry1.bundle.js</code> which contains the complete code from <code>entry1.js</code>, a requirement for <code>jquery</code> and does not contain the runtime</li>
<li><code>entry2.bundle.js</code> which contains the complete code from <code>entry2.js</code>, a requirement for <code>jquery</code> and does not contain the runtime</li>
<li><code>vendors.bundle.js</code> which contains the complete code from <code>jquery</code> and <code>some_jquery_plugin</code> and does not contain the runtime</li>
<li><code>manifest.bundle.js</code> which contains requirements for every other bundle and contains the runtime</li>
</ul>

<p>This way we end up with some smaller bundles overall and the runtime is contained in the <code>manifest</code> bundle. This is the ideal case.</p></li>
</ul>

<h1>What I do not understand/I am not sure I understand</h1>

<ul>
<li><p>In <strong>CASE 2</strong> why did we end up with the <code>vendors</code> bundle containing both the common code (<code>jquery</code>) and whatever remained from the <code>vendors</code> entry (<code>some_jquery_plugin</code>)? From my understanding, what the <code>CommonsChunkPlugin</code> did here was that it gathered the common code (<code>jquery</code>), and since we forced it to output it to the <code>vendors</code> bundle, it kind of "merged" the common code into the <code>vendors</code> bundle (which now only contained the code from <code>some_jquery_plugin</code>). <strong>Please confirm or explain.</strong> </p></li>
<li><p>In <strong>CASE 3</strong> I do not understand what happened when we passed <code>{ names : ['vendors', 'manifest'] }</code> to the plugin. Why/how was the <code>vendors</code> bundle kept intact, containing both <code>jquery</code> and <code>some_jquery_plugin</code>, when <code>jquery</code> is clearly a common dependency, and why was the generated <code>manifest.bundle.js</code> file created the way it was created (requiring all other bundles and containing the runtime) ?</p></li>
</ul>