-
-
Notifications
You must be signed in to change notification settings - Fork 8.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Webpack 4 splitChunks causes reused chunks to not be executed #7230
Comments
I've gotten this to behave slightly better by adding this to my chunkGroup test: if (module.depth === 0) {
return false;
} but it still doesn't work as expected. |
This seems to maybe be happening intentionally here: webpack/lib/optimize/SplitChunksPlugin.js Lines 559 to 565 in 2986ab1
However it isn't clear to me from the code or the commit message (added by 18ae73d) why this behavior exists. If I disable this entrypoint removal, I get the build that I expect and my program runs as expected. It seems that this logic should either be removed or perhaps there should be an option added to cacheGroups that allows a cacheGroup to also be an entrypoint. |
I am working in a complicated app that has a bunch of bundles on every page. Most of these are "global" bundles and appear on every page. So, I have configured webpack to prevent any modules that appear in these bundles from appearing in any other bundle via splitChunks. More context on this here: https://stackoverflow.com/questions/49163684/how-to-configure-webpack-4-to-prevent-chunks-from-list-of-entry-points-appearing Unfortunately, it seems that when I configure splitChunks in this way, it causes the global bundles to not be executed. In the debugging I've done, it seems that this splitChunks configuration causes the executeModules part of the bundle that the runtime chunk is looking for to be undefined. I believe this happens in the SplitChunks plugin to any reused chunk that was already an entry point. I'm not entirely sure why this was done this way, so to address my use-case, I am adding an option to cacheGroups that allows the entrypoint to be preserved when moving chunks into it. Fixes webpack#7230
I came across the same issue. In my old webpack config the 'common' chunk served both as a chunk with shared modules and an entry point. As a workaround I ended up having two chunks: 'common' and 'common-entry'. They are always included on all pages together - so there is no good reason for them not to be a single file. |
@amakhrov if you got it working, do you mind sharing your config? I am still struggling to convert to webpack 4 because of this issue. |
@IanVS here you go:
|
I tried it all the ways around but could not get a single vendors chunk. So, i have following two extract vendors and vendors-entry as @amakhrov. Are there any solution to get a single vendor chunk?
|
@expressiveco your config looks ok to me. It should create a What doesn't go as expected here for you? |
So I want vendors and vendors-entry chunks combined into a single chunk. As you concerned, it is not sensible to have multiple chunks when they will be included in all pages. |
The workaround is to get rid of
|
So, how should be the test function? My vendors.ts contains imports for modules. How could i simply test for them, one by one for each module? |
It depends on how you define 'vendor' modules. See the test function in my example above. The function takes the name of the module and the array of chunks which have this module included. If you want to extract all modules used by your vendor-entry file, you would do smth like
|
@amakhrov now i have following(minChunks:2) per your recommendation, but main.js is around 3mb and vendors.js is 700kb but i want all those code in vendors.js instead of main.js. And when minChunks:1, everything is in vendor.js but the page that loads subPageEntry bundle could not access to the output.library variable, it is undefined.
|
I applied solution of @lencioni but it did not work, only the module.depth part worked.
So, as i checked with following, manifest.js is not included in chunk groups when
|
I believe this would extract all non-top-level modules from |
Finally, i could get a single vendors bundle that contains all vendor code while keeping the code of top-level entries in their own bundle.
|
You could use DllPlugin and DllReferencePlugin for code splitting and ExecutableDllPlugin to execute a bundle with shared modules. |
I am working in a complicated app that has a bunch of bundles on every page. Most of these are "global" bundles and appear on every page. So, I have configured webpack to prevent any modules that appear in these bundles from appearing in any other bundle via splitChunks. More context on this here: https://stackoverflow.com/questions/49163684/how-to-configure-webpack-4-to-prevent-chunks-from-list-of-entry-points-appearing Unfortunately, it seems that when I configure splitChunks in this way, it causes the global bundles to not be executed. In the debugging I've done, it seems that this splitChunks configuration causes the executeModules part of the bundle that the runtime chunk is looking for to be undefined. I believe this happens in the SplitChunks plugin to any reused chunk that was already an entry point. I'm not entirely sure why this was done this way, so to address my use-case, I am adding an option to cacheGroups that allows the entrypoint to be preserved when moving chunks into it. Fixes webpack#7230
I am working in a complicated app that has a bunch of bundles on every page. Most of these are "global" bundles and appear on every page. So, I have configured webpack to prevent any modules that appear in these bundles from appearing in any other bundle via splitChunks. More context on this here: https://stackoverflow.com/questions/49163684/how-to-configure-webpack-4-to-prevent-chunks-from-list-of-entry-points-appearing Unfortunately, it seems that when I configure splitChunks in this way, it causes the global bundles to not be executed. In the debugging I've done, it seems that this splitChunks configuration causes the executeModules part of the bundle that the runtime chunk is looking for to be undefined. I believe this happens in the SplitChunks plugin to any reused chunk that was already an entry point. I'm not entirely sure why this was done this way, so to address my use-case, I am adding an option to cacheGroups that allows the entrypoint to be preserved when moving chunks into it. Fixes webpack#7230
I am working in a complicated app that has a bunch of bundles on every page. Most of these are "global" bundles and appear on every page. So, I have configured webpack to prevent any modules that appear in these bundles from appearing in any other bundle via splitChunks. More context on this here: https://stackoverflow.com/questions/49163684/how-to-configure-webpack-4-to-prevent-chunks-from-list-of-entry-points-appearing Unfortunately, it seems that when I configure splitChunks in this way, it causes the global bundles to not be executed. In the debugging I've done, it seems that this splitChunks configuration causes the executeModules part of the bundle that the runtime chunk is looking for to be undefined. I believe this happens in the SplitChunks plugin to any reused chunk that was already an entry point. I'm not entirely sure why this was done this way, so to address my use-case, I am adding an option to cacheGroups that allows the entrypoint to be preserved when moving chunks into it. Fixes webpack#7230
I am working in a complicated app that has a bunch of bundles on every page. Most of these are "global" bundles and appear on every page. So, I have configured webpack to prevent any modules that appear in these bundles from appearing in any other bundle via splitChunks. More context on this here: https://stackoverflow.com/questions/49163684/how-to-configure-webpack-4-to-prevent-chunks-from-list-of-entry-points-appearing Unfortunately, it seems that when I configure splitChunks in this way, it causes the global bundles to not be executed. In the debugging I've done, it seems that this splitChunks configuration causes the executeModules part of the bundle that the runtime chunk is looking for to be undefined. I believe this happens in the SplitChunks plugin to any reused chunk that was already an entry point. I'm not entirely sure why this was done this way, so to address my use-case, I am adding an option to cacheGroups that allows the entrypoint to be preserved when moving chunks into it. Fixes webpack#7230
I am working in a complicated app that has a bunch of bundles on every page. Most of these are "global" bundles and appear on every page. So, I have configured webpack to prevent any modules that appear in these bundles from appearing in any other bundle via splitChunks. More context on this here: https://stackoverflow.com/questions/49163684/how-to-configure-webpack-4-to-prevent-chunks-from-list-of-entry-points-appearing Unfortunately, it seems that when I configure splitChunks in this way, it causes the global bundles to not be executed. In the debugging I've done, it seems that this splitChunks configuration causes the executeModules part of the bundle that the runtime chunk is looking for to be undefined. I believe this happens in the SplitChunks plugin to any reused chunk that was already an entry point. I'm not entirely sure why this was done this way, so to address my use-case, I am adding an option to cacheGroups that allows the entrypoint to be preserved when moving chunks into it. Fixes webpack#7230
I am working in a complicated app that has a bunch of bundles on every page. Most of these are "global" bundles and appear on every page. So, I have configured webpack to prevent any modules that appear in these bundles from appearing in any other bundle via splitChunks. More context on this here: https://stackoverflow.com/questions/49163684/how-to-configure-webpack-4-to-prevent-chunks-from-list-of-entry-points-appearing Unfortunately, it seems that when I configure splitChunks in this way, it causes the global bundles to not be executed. In the debugging I've done, it seems that this splitChunks configuration causes the executeModules part of the bundle that the runtime chunk is looking for to be undefined. I believe this happens in the SplitChunks plugin to any reused chunk that was already an entry point. I'm not entirely sure why this was done this way, so to address my use-case, I am adding an option to cacheGroups that allows the entrypoint to be preserved when moving chunks into it. Fixes webpack#7230
I was meet the same issue, and I am looking forward to the merge request could be accepted. |
I am working in a complicated app that has a bunch of bundles on every page. Most of these are "global" bundles and appear on every page. So, I have configured webpack to prevent any modules that appear in these bundles from appearing in any other bundle via splitChunks. More context on this here: https://stackoverflow.com/questions/49163684/how-to-configure-webpack-4-to-prevent-chunks-from-list-of-entry-points-appearing Unfortunately, it seems that when I configure splitChunks in this way, it causes the global bundles to not be executed. In the debugging I've done, it seems that this splitChunks configuration causes the executeModules part of the bundle that the runtime chunk is looking for to be undefined. I believe this happens in the SplitChunks plugin to any reused chunk that was already an entry point. I'm not entirely sure why this was done this way, so to address my use-case, I am adding an option to cacheGroups that allows the entrypoint to be preserved when moving chunks into it. Fixes webpack#7230
Running into this same issue and it's preventing us from updating https://github.com/prebid/Prebid.js from webpack v3 to v4. We have a unique (until I saw this thread, maybe some here are doing the same) issue where we have 100+ entry points with 1 entry point being the "core" module that contains shared code across all of the other entry points. This allows us to split our code into jsonp fragments and build dynamic bundles at runtime through concatenating the resulting build files depending on which additional code we want. This pattern is the foundation for our Prebid.js code module system. I can emulate the right build output using splitChunks in webpack 4 (verified with the webpack-bundle-analyzer) except that in the webpack 4 bundle the "core" module entry point is never executed even though the other entry points are. I have a simple reproduction of our issue here that I made before I found this issue: https://github.com/snapwich/webpack4-chunk-bug As @lencioni mentioned as well, I can confirm that removing this code from the splitChunks plugin seems to fix the issue: // If the chosen name is already an entry point we remove the entry point
const entrypoint = compilation.entrypoints.get(chunkName);
// commenting this code out fixes the issue
// if (entrypoint) {
// compilation.entrypoints.delete(chunkName);
// entrypoint.remove();
// newChunk.entryModule = undefined;
// } |
@snapwich DllPlugin /DllReferencePlugin provided by webpack should give you more control over code splitting. You could use them with ExecutableDllPlugin to execute particular entry points within the resulted bundle. |
@snapwich , I found that you are using enforce: true in splitchunks cacheGroups which is not allowing the common chunk (entry) to execute. Removing it worked for me. |
|
I am working in a complicated app that has a bunch of bundles on every page. Most of these are "global" bundles and appear on every page. So, I have configured webpack to prevent any modules that appear in these bundles from appearing in any other bundle via splitChunks. More context on this here: https://stackoverflow.com/questions/49163684/how-to-configure-webpack-4-to-prevent-chunks-from-list-of-entry-points-appearing Unfortunately, it seems that when I configure splitChunks in this way, it causes the global bundles to not be executed. In the debugging I've done, it seems that this splitChunks configuration causes the executeModules part of the bundle that the runtime chunk is looking for to be undefined. I believe this happens in the SplitChunks plugin to any reused chunk that was already an entry point. I'm not entirely sure why this was done this way, so to address my use-case, I am adding an option to cacheGroups that allows the entrypoint to be preserved when moving chunks into it. Fixes webpack#7230
I am working in a complicated app that has a bunch of bundles on every page. Most of these are "global" bundles and appear on every page. So, I have configured webpack to prevent any modules that appear in these bundles from appearing in any other bundle via splitChunks. More context on this here: https://stackoverflow.com/questions/49163684/how-to-configure-webpack-4-to-prevent-chunks-from-list-of-entry-points-appearing Unfortunately, it seems that when I configure splitChunks in this way, it causes the global bundles to not be executed. In the debugging I've done, it seems that this splitChunks configuration causes the executeModules part of the bundle that the runtime chunk is looking for to be undefined. I believe this happens in the SplitChunks plugin to any reused chunk that was already an entry point. I'm not entirely sure why this was done this way, so to address my use-case, I am adding an option to cacheGroups that allows the entrypoint to be preserved when moving chunks into it. Fixes webpack#7230
Had the same issue in context of:
Problem: When SiteHeader and SiteFooter are added to common bundle entrypoint, they do not get exposed as a result. Even when i use them along with appropriate entryPoint. Suggested solution: is probably to move exposed header and footer on to another entrypoint, but that requires reworking server-side (changing bundle script tags). Accepted solution: we went with adding SiteHeader and SiteFooter to every entrypoint by a function like this:
Looking like this in the end:
|
Hi, can Any1 help me convert common chunk to split chunks |
We have the same problem and no solution to it. 😞 If there is anything else we can provide to help tracking down the issue let me now. Webpack version: ^4.34.0 const waAliases = require('../config/webpack-aliases');
const waEntries = require('../config/entry-files');
const path = require('path');
const webpack = require('webpack');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const { VueLoaderPlugin } = require('vue-loader');
const CompressionPlugin = require('compression-webpack-plugin');
console.log(waAliases);
module.exports = {
watch: false,
watchOptions: {
ignored: /node_modules/
},
entry: waEntries,
output: {
filename: '[name].js',
path: path.resolve(__dirname, '../../webroot/'),
},
resolve: {
extensions: ['.js', '.vue'],
alias: waAliases
},
module: {
rules: [
{
test: /\.js$/,
include: /(src)/,
exclude: /(node_modules|bower_components)/,
use: {
loader: 'babel-loader',
options: {
presets: ['es2015', 'stage-0']
}
}
},
{
test: /\.(woff|woff2|eot|ttf|svg)(\?.*$|$)/,
loader: 'file-loader?name=[name].[ext]?[hash]',
},
{
test: /\.vue$/,
loader: 'vue-loader',
},
{ // sass / scss loader for webpack
test: /\.(css)$/,
use: [
'vue-style-loader',
'css-loader',
]
},
{
test: /\.(sass|scss)$/,
use: ExtractTextPlugin.extract({
fallback: 'style-loader',
use: ['css-loader', 'sass-loader']
})
}
]
},
optimization: {
splitChunks: {
chunks: 'all',
minSize: 30000,
minChunks: 1,
maxAsyncRequests: 5,
maxInitialRequests: 3,
automaticNameDelimiter: '~',
name: true,
cacheGroups: {
commons: {
test: /[\\/]node_modules[\\/]/,
name: 'js/public/wa-common',
chunks: 'all'
}
}
}
},
devtool: 'source-map',
plugins: [
new VueLoaderPlugin(),
new webpack.ProvidePlugin({
Vue: ['vue/dist/vue.esm.js', 'default'],
jQuery: 'jquery',
VueI18n: 'vue-i18n',
$: 'jquery',
'window.jQuery': 'jquery',
}),
new CompressionPlugin(),
new ExtractTextPlugin({ // define where to save the file
filename: 'css/[name].css',
allChunks: true,
})
]
}; |
Did you try the solution I mentioned above? It helped us overcome current webpack limitations. The whole idea is that you append common chunk to each entry point. As a result, the EXECUTION part lands in each of the entry point scripts, while your common chunk still keeps all the common code. And when used together, you get the desired effect. At least in our case, problem was caused by the fact, that if you want to add a "common" library-chunk. And that common library has some execution layer. That layer is not included anywhere, unless this common chunk is not declared as a real entry point. (So just the fact that your entry point chunk is using the code from common one - counts out) |
Should work with |
Bug report
I am working in a complicated app that has a bunch of bundles on every page. Most of these are "global" bundles and appear on every page. So, I have configured webpack to prevent any modules that appear in these bundles from appearing in any other bundle via splitChunks. More context on this here: https://stackoverflow.com/questions/49163684/how-to-configure-webpack-4-to-prevent-chunks-from-list-of-entry-points-appearing
What is the current behavior?
It seems that when I configure splitChunks in this way, it causes the global bundles to not be executed.
If the current behavior is a bug, please provide the steps to reproduce.
Here's a branch on a repo that reproduces this issue: https://github.com/lencioni/webpack-splitchunks-playground/tree/splitchunks-execution-problem
In this repro case, it currently logs the following to the console:
In the debugging I've done, it seems that this splitChunks configuration causes the
executeModules
part of the bundle that the runtime chunk is looking for to beundefined
.What is the expected behavior?
The code in the "global" bundles should be executed, which should cause the console log to look more like this:
Other relevant information:
webpack version: 4.8.1
Node.js version: 8.9.1
Operating System: Mac
Additional tools:
The text was updated successfully, but these errors were encountered: