Which splitChunks settings keep chunk filenames stable across dependency updates in webpack 5?
0 reputation · 18 May 2020, 11:02 UTC
0 reputation · 18 May 2020, 11:02 UTC
In webpack 5 production builds, splitChunks separates shared modules into distinct chunks based on the module graph. When a dependency version changes, the resolved module paths and sizes can shift, which may alter how splitChunks assigns chunk IDs and names between rebuilds. This matters when output.filename uses patterns like [name] or [contenthash] together with splitChunks cacheGroups, because a shifted chunk name can collide with a previously cached file or break long-term caching assumptions.
The behavior differs between webpack 4 and 5, and settings such as optimization.splitChunks.chunks (async, initial, all) or enforce rules can make the chunk graph less deterministic after an update. Teams relying on stable URLs for CDN caching or service workers need to know which configuration choices keep chunk identifiers consistent when only dependency versions change.
Which splitChunks configuration options in webpack 5 guarantee stable chunk names across dependency version updates, and does setting a fixed name in cacheGroups prevent the cache key collisions described above?
35775 reputation · 18 May 2020, 18:59 UTC
No splitChunks setting alone guarantees stable chunk names when dependency versions change the module graph. The only reliable way to keep filenames stable for caching is to include [contenthash] (or [chunkhash]) in output.filename. A fixed name in a cacheGroup keeps the chunk's name constant, but if the chunk's module composition changes, its content hash changes — producing a new filename. The collision risk you describe (an old file being overwritten) only occurs when [name] is used without a content hash.
optimization.chunkIds: 'deterministic' and optimization.moduleIds: 'deterministic'. These stabilize the numeric IDs and module hashes that feed into chunk content hashes.output.filename: '[name].[contenthash].js' (and chunkFilename for async chunks). The filename changes only when the chunk's actual content changes.splitChunks.chunks: 'async' (the default) instead of 'all'. Extracting only dynamic imports reduces churn when dependency updates shift module sizes or paths.enforce: true: It bypasses minSize/minChunks thresholds, making chunk composition depend solely on graph topology — highly sensitive to version changes.cacheGroup.name Does (and Doesn't)Setting cacheGroups: { vendor: { name: 'vendor', test: /node_modules/, chunks: 'async' } } forces the vendor chunk to always be named vendor. This prevents the name from being auto-generated (e.g., vendors-node_modules_lodash_... ) and shifting between builds. However:
test, the chunk's content changes → new [contenthash] → new filename (correct cache invalidation).[contenthash] and rely on [name] alone, a shifting auto-generated name or a fixed name that now contains different modules will write to the same output path, overwriting the old file — the collision you're worried about.name cause build errors; webpack requires unique chunk names.module.exports = {
optimization: {
splitChunks: {
chunks: 'async', // default; limits extraction to dynamic imports
cacheGroups: {
vendor: {
name: 'vendor', // stable name for readability/debugging
test: /[\\/]node_modules[\\/]/,
priority: -10
}
}
}
},
output: {
filename: '[name].[contenthash].js',
chunkFilename: '[name].[contenthash].js'
}
};
lodash@4.17.21). Record the vendor chunk filename (e.g., vendor.a1b2c3.js).lodash@4.17.22), rebuild, and compare:
vendor → vendors-xyz) → a cacheGroup lacks a fixed name or chunks: 'all' reshuffled modules.optimization.chunkIds and moduleIds are 'deterministic' via webpack --json | jq '.optimization.chunkIds'.Are you using output.filename: '[name].js' (no hash) for any entry or chunk, or relying on a service worker / CDN that keys cache entries by [name] alone? If yes, the fixed name helps but content changes will still overwrite the same URL — add [contenthash] to the filename pattern.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.