Issue 1:
Do you want to request a feature or report a bug?

bug

What is the current behavior?

Chunks generated by System.import or import do not affected by CommonsChunkPlugin.

If the current behavior is a bug, please provide the steps to reproduce.

demo rep

sources structure

src
|- modules
| |- module0.js
| |- module1.js
|- index.js

webpack.config.js

const path = require('path');
const webpack = require("webpack");

module.exports = {
entry: {
index: './src/index.js'
},
output: {
filename: '[name].js',
path: path.resolve(__dirname, 'dist'),
publicPath: 'dist/'
},
plugins: [
new webpack.optimize.CommonsChunkPlugin({
name: "vendors",
minChunks: function(module) {
return module.resource && (/node_modules/).test(module.resource);
}
})
]
};

index.js

for (let i = 0; i < 2; i++) {
System.import("./modules/module" + i).then((module) => module.default());
}

modules/module0.js && modules/module1.js

import * as _ from "lodash";
export default () => console.log(_.random(100));

Generated chunks for module0 & module1 both has copy of lodash and vendors.js is empty.

What is the expected behavior?

Dynamically generated chunks must be affected by CommonsChunkPlugin in same way as entry points.

Please mention other relevant information such as the browser version, Node.js version, webpack version and Operating System.

node 7.0.0, webpack 2.2.1, OSX

Issue 2:
Do you want to request a feature or report a bug?

Feature for CommonChunkPlugin.

Support selecting modules from non-entry chunks. Meaning, select statically imported modules from chunks that were created from a dynamic import (require.ensure / System.import / import(".."))

What is the current behavior?

Currently CommonChunkPlugin only receives modules imported from entry chunks.

What is the expected behavior?

CommonChunkPlugin should receive also modules from non-entry chunks.

Another option will be that the default behavior will be that the plugin won't be getting these modules and only with passing something like selectAllChunks: true will enable this behavior.

If this is a feature request, what is motivation or use case for changing the behavior?

Most of the examples out there talks about CodeSplitting but not talking about CodeSplitting with lazy loading. For example, load your main page as an entry chunk, and split the rest of your website routes to different chunks and only load those on demand.

You see the important need for this feature when you're trying to make a vendors chunk that will include the vendors from ALL the chunks including the ones for the different routes that are being created from a dynamic import as a split point.

In our opinion the best solution to create the vendors chunk will be using the minChunks function since the other two (specifying hard coded which packages to take / import package.json.dependencies) has a lot of issues with and this is the most dynamic way to do it:

new webpack.optimize.CommonsChunkPlugin({
name: 'vendors',
minChunks: ({ resource }) => /node_modules/.test(resource)
})

The problem is that since CommonsChunkPlugin only gets modules form the entry chunks, so all the vendors from our different split points are not being added to this chunk.

The motivation around this feature request is that others won't need to do the workaround I'll show here.

Proposed temporary workaround and why it's not that good. Writing it here anyway so who ever needs it will see it and would be able to use it

What the lack of this feature forces us to do it for every dynamic import we're doing (using import("path")) we're also going and creating an entry chunk for it. Just so the above code will work.

Then, all of these "duplicate" chunks we're excluding from being added to the HTML using the excludeChunks of HtmlWebpackPlugin

So it basically looks like this:

...

// Why do we need to exclude these entries?
// The entries here are being dynamically loaded per route in the application so we would like to set
// them to be excluded form HtmlWebpackPlugin auto inject of entry chunks.
//
// If they are being dynamically loaded in the system, so why do you need them here at all?
// We're creating a `vendors` chunk automatically from what being imported from `node_modules`, in order for webpack
// to know about what code exists in these route chunks we need to set them as entries here.
// That way we're getting everything we ever wanted! The `vendors` is being created out of ALL the vendors in the system,
// and we're still able to dynamically load these chunks per route without having them injected to index.html at the beginning.
const excludeEntries = {
main: [path.join(chunksPath, 'main_chunk')],
A_template_collection: [path.join(pagesPath, 'TemplateCollectionPage')],
A_template_wizard: [path.join(pagesPath, 'TemplateWizardPage')],
A_edit_template: [path.join(pagesPath, 'TemplateEditPage')],
A_create_instance: [path.join(pagesPath, 'CreateInstancePage')],
B_issues_collection: [path.join(pagesPath, 'IssuesCollectionPage')]
};

const entry = Object.assign({}, excludeEntries, {
application: [path.join(chunksPath, 'application_chunk')]
});

const config = {
entry,
...
plugins: [
new webpack.optimize.CommonsChunkPlugin({
name: 'vendors',
minChunks: ({ resource }) => /node_modules/.test(resource)
}),
new HtmlWebpackPlugin({
title: indexHtmlTitle,
resourceHintsMetaTags,
inject: true,
template: indexHtmlPath,
excludeChunks: Object.keys(excludeEntries)
}),
]
...
}

The dynamic imports are being used on the same paths as the entry chunks that are being excluded from the html.

This causes some difficulties for us:

If you dynamically import something and forget to put it here as well it will not go into the vendors chunks and you'll lose cache

This creates for us chunks that we're not actually using. So for the same code I'll have the named entry chunk and I'll also have a chunk from the dynamic import. I'm not using the named entry-chunks but it's just noise to me.

That is even bigger when also using the ExtractTextPlugin.

I looked also here: https://github.com/oieduardorabelo/webpack-commonschunkplugin-dynamic-splitting

But that seems to not be related since in our case the only real entry point (application: [path.join(chunksPath, 'application_chunk')]) is basically just loading polyfills + loading the main chunk path dynamically. Since all the application chunk is doing is mainly dynamically import() stuff it has no static imports of files from node_modules. So CommonChunkPlugin doesn't catch that..

Please mention other relevant information such as the browser version, Node.js version, webpack version and Operating System.

OS: macOS 10.12.3

Node.js version: 6.9.10

Webpack version: 2.2.1

Browser not relavant