Issue 1:
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

Issue 2:
I am running across a bug where Webpack generates an invalid Javascript file when running in watch mode. This bug occurs 100% of the time, the first time I modify Cards.js in watch mode. Once the file is in a bad state, I keep on getting the following error:

undefined is not a function
__webpack_require__@http://localhost:8080/com/realestate/frontend/page/Common.js:51:30
Object.webpackJsonp.0@http://localhost:8080/com/realestate/frontend/page/Cards.js:21:2
__webpack_require__@http://localhost:8080/com/realestate/frontend/page/Common.js:51:30
webpackJsonpCallback@http://localhost:8080/com/realestate/frontend/page/Common.js:22:20
(?)()@http://localhost:8080/com/realestate/frontend/page/Cards.js:1:1Common.js:1256 printUncaughtErrorCommon.js:1285 window.onerror
Common.js:51 Uncaught TypeError: undefined is not a function

The only way to fix the problem is to clean-build the entire project (further incremental changes to the file do not fix the problem).

Here is a copy of Common.js: https://gist.github.com/cowwoc/b752cf667c049af05cec

Here is a copy of Cards.js: https://gist.github.com/cowwoc/5cfcc58edc3b1a8aee40

I am modifying Cards.js line 54 over and over in order to trigger this problem.

I walked through the code and discovered that the browser hits line 51 with module[moduleId] equal to 29. This is problematic for two reasons:

Usually module[moduleId] points to a function, not a number.

Module 29 is generated by a call to require("./ResourceTable.scss"). If you look for it in Common.js you will notice it is not defined.