Dependencies not properly shared across pages and _app.js
Create a number of pages. Add a module to _app.js.
Increase the number of times a module is included from once to N times, track progress
Takes at least 2 pages for a dep included in _app.js to be factored out.
Once a module has been included in _app, it should never be packed again.
In a 4 page + _app + _document app
// _app only (_app.js includes Auth)

// 1 page (_app.js + submit.js include Auth)

// 2 pages (_app.js + submit.js + scorecard.js include Auth)

Related to: #3818 (though in this case import isn't being exported as in HOC)
Related to: #118 and #253
Potential solutions: expose or document modifying the threshold for placing a dependency in the common bundle.
However, it seems there should be a more intelligent procedure, in which unnecessary data is not bundled for any descendants of _app.js.
Fixed by
if (!options.isServer) {
config.optimization.splitChunks.cacheGroups.commons.minChunks = 2;
}
This is a simple fix, effectively just needs documentation of default of 3. This may be somewhat confusing, as Webpack's default is 1, and "shared" implies 2.
@akotlar that snippet seems out of date when investigating the cacheGroups object returned by the most recent version of webpack bundled with Next:
After console.logging(config.optimizations.splitChunks.cacheGroups) on startup (with zeit/next-css generating the "styles" prop):
{ cacheGroups:
{ default: false,
vendors: false,
styles:
{ name: 'styles',
test: /\.+(css)$/,
chunks: 'all',
enforce: true }
}
}
Looking at the documentation for the SplitChunksPlugin it seems you can set up the commons object as you are suggesting; I am wondering if that or either of these lines would do the trick on newer versions:
if (!isServer) {
const chunkingDefaults = { minChunks: 2, reuseExistingChunk: true };
config.optimization.splitChunks.cacheGroups.default = chunkingDefaults;
config.optimization.splitChunks.minChunks = 2;
}
I can confirm this is happening with our app bundles too.
@dav-is is working on fixing this.
Cheering for fixing this as well.. Our app is 2x more heavy than necessary because of this bug
Currently I have best results when using following:
if (!isServer) {
const cacheGroups = config.optimization.splitChunks.cacheGroups
delete cacheGroups.react
cacheGroups.default = false
cacheGroups.vendors = {
name: 'vendors',
test: /[\\/](node_modules|packages)[\\/]/,
enforce: true,
priority: 20
}
cacheGroups.commons = {
name: 'commons',
minChunks: 2,
priority: 10
}
}
This forces all dependencies from node_modules to vendor chunk (nice, because yarn.lock ensures this chunk won't change very often), then it forces all common non-vendor application code to commons chunk (nice because pages are loading faster when browsing on client side).
The only issue I have currently is that _app.js is separate page while I'd like it to be a part of commons chunk... Also runtime chunk that I'd like also to be a part of commons chunk. Any help appreciated..
Any updates regarding this issue?
This should be fixed in https://github.com/zeit/next.js/pull/7696
module.exports = {
experimental: {
granularChunks: true
}
}
Closing this as it should be solved by #7696
I'm still seeing an overlapping @apollo/client in _app.js, even with granularChunks enabled:

And if I manually split the chunks, it still overlaps a decent amount of code (should be ~30kb gzipped total, but is more like 50kb gzipped combined):
const regexWithApollo = /(?<!node_modules.*)[\\/]node_modules[\\/](react|react-dom|scheduler|prop-types|use-subscription|@apollo\/client)[\\/]/;
config.optimization.splitChunks.cacheGroups.framework.test = regexWithApollo;

Any ideas?
@switz it might not be what is causing your specific issue, but note that @apollo/client publishes code duplicated in separate ESM (faux ESM, not Node.js compatible) and CJS files:
https://unpkg.com/browse/@apollo/client@3.1.4/
Depending how multiple modules require or import from the various files, you could end up encountering the dual package hazard.
Most helpful comment
@dav-is is working on fixing this.