From 6014ca7e8671f7daefbe11e6496847a16234a42b Mon Sep 17 00:00:00 2001 From: Tobias Koppers Date: Mon, 13 Jul 2020 10:12:17 +0200 Subject: [PATCH 1/4] splitChunks improvements add new splitChunks.enforceSizeThreshold option enforces splitting on certain size (ignoring maxRequests and minRemainingSize) reduce default for splitChunks.minSize to 20k set default for splitChunks.enforceSizeThreshold to 50k fix bug where sorting didn't work for minSize: 0 --- declarations/WebpackOptions.d.ts | 8 ++ lib/config/defaults.js | 3 + lib/optimize/SplitChunksPlugin.js | 206 +++++++++++++++++------------- schemas/WebpackOptions.json | 16 +++ types.d.ts | 12 ++ 5 files changed, 157 insertions(+), 88 deletions(-) diff --git a/declarations/WebpackOptions.d.ts b/declarations/WebpackOptions.d.ts index 40d0eb6e7..7817b8f56 100644 --- a/declarations/WebpackOptions.d.ts +++ b/declarations/WebpackOptions.d.ts @@ -1372,6 +1372,10 @@ export interface OptimizationSplitChunksOptions { chunks?: | ("initial" | "async" | "all") | ((chunk: import("../lib/Chunk")) => boolean); + /** + * Size threshold at which splitting is enforced and other restrictions (minRemainingSize, maxAsyncRequests, maxInitialRequests) are ignored. + */ + enforceSizeThreshold?: OptimizationSplitChunksSizes; /** * Options for modules not selected by any other cache group. */ @@ -1465,6 +1469,10 @@ export interface OptimizationSplitChunksCacheGroup { * Ignore minimum size, minimum chunks and maximum requests and always create chunks for this cache group. */ enforce?: boolean; + /** + * Size threshold at which splitting is enforced and other restrictions (minRemainingSize, maxAsyncRequests, maxInitialRequests) are ignored. + */ + enforceSizeThreshold?: OptimizationSplitChunksSizes; /** * Sets the template for the filename for created chunks. */ diff --git a/lib/config/defaults.js b/lib/config/defaults.js index fb84b9e4c..b71877187 100644 --- a/lib/config/defaults.js +++ b/lib/config/defaults.js @@ -582,6 +582,9 @@ const applyOptimizationDefaults = ( D(splitChunks, "minChunks", 1); F(splitChunks, "minSize", () => (production ? 30000 : 10000)); F(splitChunks, "minRemainingSize", () => (development ? 0 : undefined)); + F(splitChunks, "enforceSizeThreshold", () => + production ? undefined : 100000 + ); F(splitChunks, "maxAsyncRequests", () => (production ? 30 : Infinity)); F(splitChunks, "maxInitialRequests", () => (production ? 30 : Infinity)); D(splitChunks, "automaticNameDelimiter", "-"); diff --git a/lib/optimize/SplitChunksPlugin.js b/lib/optimize/SplitChunksPlugin.js index 8f7bcfa4c..8702dfa6c 100644 --- a/lib/optimize/SplitChunksPlugin.js +++ b/lib/optimize/SplitChunksPlugin.js @@ -58,6 +58,7 @@ const MinMaxSizeWarning = require("./MinMaxSizeWarning"); * @property {boolean=} enforce * @property {SplitChunksSizes} minSize * @property {SplitChunksSizes} minRemainingSize + * @property {SplitChunksSizes} enforceSizeThreshold * @property {SplitChunksSizes} maxAsyncSize * @property {SplitChunksSizes} maxInitialSize * @property {number=} minChunks @@ -75,10 +76,9 @@ const MinMaxSizeWarning = require("./MinMaxSizeWarning"); * @property {number=} priority * @property {GetName=} getName * @property {ChunkFilterFunction=} chunksFilter - * @property {boolean=} enforce * @property {SplitChunksSizes} minSize * @property {SplitChunksSizes} minRemainingSize - * @property {SplitChunksSizes} minSizeForMaxSize + * @property {SplitChunksSizes} enforceSizeThreshold * @property {SplitChunksSizes} maxAsyncSize * @property {SplitChunksSizes} maxInitialSize * @property {number=} minChunks @@ -88,6 +88,10 @@ const MinMaxSizeWarning = require("./MinMaxSizeWarning"); * @property {string=} idHint * @property {string} automaticNameDelimiter * @property {boolean=} reuseExistingChunk + * @property {boolean} _validateSize + * @property {boolean} _validateRemainingSize + * @property {SplitChunksSizes} _minSizeForMaxSize + * @property {boolean} _conditionalEnforce */ /** @@ -124,6 +128,7 @@ const MinMaxSizeWarning = require("./MinMaxSizeWarning"); * @property {ChunkFilterFunction} chunksFilter * @property {SplitChunksSizes} minSize * @property {SplitChunksSizes} minRemainingSize + * @property {SplitChunksSizes} enforceSizeThreshold * @property {SplitChunksSizes} maxInitialSize * @property {SplitChunksSizes} maxAsyncSize * @property {number} minChunks @@ -141,8 +146,8 @@ const MinMaxSizeWarning = require("./MinMaxSizeWarning"); * @typedef {Object} ChunksInfoItem * @property {SortableSet} modules * @property {CacheGroup} cacheGroup + * @property {number} cacheGroupIndex * @property {string} name - * @property {boolean} validateSize * @property {Record} sizes * @property {Set} chunks * @property {Set} reuseableChunks @@ -220,12 +225,15 @@ const compareEntries = (a, b) => { const bSizeReduce = totalSize(b.sizes) * (b.chunks.size - 1); const diffSizeReduce = aSizeReduce - bSizeReduce; if (diffSizeReduce) return diffSizeReduce; - // 4. by number of modules (to be able to compare by identifier) + // 4. by cache group index + const indexDiff = a.cacheGroupIndex - b.cacheGroupIndex; + if (indexDiff) return indexDiff; + // 5. by number of modules (to be able to compare by identifier) const modulesA = a.modules; const modulesB = b.modules; const diff = modulesA.size - modulesB.size; if (diff) return diff; - // 5. by module identifiers + // 6. by module identifiers modulesA.sort(); modulesB.sort(); return compareModuleIterables(modulesA, modulesB); @@ -507,6 +515,7 @@ const createCacheGroupSource = (options, key) => { enforce: options.enforce, minSize: normalizeSizes(options.minSize), minRemainingSize: mergeSizes(options.minRemainingSize, options.minSize), + enforceSizeThreshold: normalizeSizes(options.enforceSizeThreshold), maxAsyncSize: mergeSizes(options.maxAsyncSize, options.maxSize), maxInitialSize: mergeSizes(options.maxInitialSize, options.maxSize), minChunks: options.minChunks, @@ -531,6 +540,7 @@ module.exports = class SplitChunksPlugin { chunksFilter: normalizeChunksFilter(options.chunks || "all"), minSize: normalizeSizes(options.minSize), minRemainingSize: mergeSizes(options.minRemainingSize, options.minSize), + enforceSizeThreshold: normalizeSizes(options.enforceSizeThreshold), maxAsyncSize: mergeSizes(options.maxAsyncSize, options.maxSize), maxInitialSize: mergeSizes(options.maxInitialSize, options.maxSize), minChunks: options.minChunks || 1, @@ -714,6 +724,7 @@ module.exports = class SplitChunksPlugin { /** * @param {CacheGroup} cacheGroup the current cache group + * @param {number} cacheGroupIndex the index of the cache group of ordering * @param {Chunk[]} selectedChunks chunks selected for this module * @param {bigint} selectedChunksKey a key of selectedChunks * @param {Module} module the current module @@ -721,6 +732,7 @@ module.exports = class SplitChunksPlugin { */ const addModuleToChunksInfoMap = ( cacheGroup, + cacheGroupIndex, selectedChunks, selectedChunksKey, module @@ -771,10 +783,8 @@ module.exports = class SplitChunksPlugin { compareModulesByIdentifier ), cacheGroup, + cacheGroupIndex, name, - validateSize: - hasNonZeroSizes(cacheGroup.minSize) || - hasNonZeroSizes(cacheGroup.minRemainingSize), sizes: {}, chunks: new Set(), reuseableChunks: new Set(), @@ -783,10 +793,8 @@ module.exports = class SplitChunksPlugin { ); } info.modules.add(module); - if (info.validateSize) { - for (const type of module.getSourceTypes()) { - info.sizes[type] = (info.sizes[type] || 0) + module.size(type); - } + for (const type of module.getSourceTypes()) { + info.sizes[type] = (info.sizes[type] || 0) + module.size(type); } if (!info.chunksKeys.has(selectedChunksKey)) { info.chunksKeys.add(selectedChunksKey); @@ -823,29 +831,35 @@ module.exports = class SplitChunksPlugin { combinationsCache.set(chunksKey, combs); } + let cacheGroupIndex = 0; for (const cacheGroupSource of cacheGroups) { /** @type {CacheGroup} */ let cacheGroup = this._cacheGroupCache.get(cacheGroupSource); if (cacheGroup === undefined) { + const minSize = mergeSizes( + cacheGroupSource.minSize, + cacheGroupSource.enforce ? undefined : this.options.minSize + ); + const minRemainingSize = mergeSizes( + cacheGroupSource.minRemainingSize, + cacheGroupSource.enforce + ? undefined + : this.options.minRemainingSize + ); + const enforceSizeThreshold = mergeSizes( + cacheGroupSource.enforceSizeThreshold, + cacheGroupSource.enforce + ? undefined + : this.options.enforceSizeThreshold + ); cacheGroup = { key: cacheGroupSource.key, priority: cacheGroupSource.priority || 0, chunksFilter: cacheGroupSource.chunksFilter || this.options.chunksFilter, - minSize: mergeSizes( - cacheGroupSource.minSize, - cacheGroupSource.enforce ? undefined : this.options.minSize - ), - minRemainingSize: mergeSizes( - cacheGroupSource.minRemainingSize, - cacheGroupSource.enforce - ? undefined - : this.options.minRemainingSize - ), - minSizeForMaxSize: mergeSizes( - cacheGroupSource.minSize, - this.options.minSize - ), + minSize, + minRemainingSize, + enforceSizeThreshold, maxAsyncSize: mergeSizes( cacheGroupSource.maxAsyncSize, cacheGroupSource.enforce @@ -892,7 +906,14 @@ module.exports = class SplitChunksPlugin { cacheGroupSource.idHint !== undefined ? cacheGroupSource.idHint : cacheGroupSource.key, - reuseExistingChunk: cacheGroupSource.reuseExistingChunk + reuseExistingChunk: cacheGroupSource.reuseExistingChunk, + _validateSize: hasNonZeroSizes(minSize), + _validateRemainingSize: hasNonZeroSizes(minRemainingSize), + _minSizeForMaxSize: mergeSizes( + cacheGroupSource.minSize, + this.options.minSize + ), + _conditionalEnforce: hasNonZeroSizes(enforceSizeThreshold) }; } // For all combination of chunk selection @@ -910,11 +931,13 @@ module.exports = class SplitChunksPlugin { addModuleToChunksInfoMap( cacheGroup, + cacheGroupIndex, selectedChunks, selectedChunksKey, module ); } + cacheGroupIndex++; } } @@ -923,13 +946,12 @@ module.exports = class SplitChunksPlugin { logger.time("queue"); // Filter items were size < minSize - for (const pair of chunksInfoMap) { - const info = pair[1]; + for (const [key, info] of chunksInfoMap) { if ( - info.validateSize && + info.cacheGroup._validateSize && !checkMinSize(info.sizes, info.cacheGroup.minSize) ) { - chunksInfoMap.delete(pair[0]); + chunksInfoMap.delete(key); } } @@ -1021,18 +1043,20 @@ module.exports = class SplitChunksPlugin { // TODO check if this check is really needed, shouldn't chunks always be non-empty? if (item.chunks.size === 0 && !isExistingChunk) continue; + const enforced = + item.cacheGroup._conditionalEnforce && + checkMinSize(item.sizes, item.cacheGroup.enforceSizeThreshold); + + const usedChunks = new Set(item.chunks); + // Check if maxRequests condition can be fulfilled - // TODO try to avoid creating a new array here - const usedChunks = Array.from(item.chunks); - - let validChunks = usedChunks; - if ( - Number.isFinite(item.cacheGroup.maxInitialRequests) || - Number.isFinite(item.cacheGroup.maxAsyncRequests) + !enforced && + (Number.isFinite(item.cacheGroup.maxInitialRequests) || + Number.isFinite(item.cacheGroup.maxAsyncRequests)) ) { - validChunks = validChunks.filter(chunk => { - // respect max requests when not enforced + for (const chunk of usedChunks) { + // respect max requests const maxRequests = chunk.isOnlyInitial() ? item.cacheGroup.maxInitialRequests : chunk.canBeInitial() @@ -1041,27 +1065,34 @@ module.exports = class SplitChunksPlugin { item.cacheGroup.maxAsyncRequests ) : item.cacheGroup.maxAsyncRequests; - return ( - !isFinite(maxRequests) || getRequests(chunk) < maxRequests - ); - }); + if ( + isFinite(maxRequests) && + getRequests(chunk) >= maxRequests + ) { + usedChunks.delete(chunk); + } + } } - validChunks = validChunks.filter(chunk => { + outer: for (const chunk of usedChunks) { for (const module of item.modules) { - if (chunkGraph.isModuleInChunk(module, chunk)) return true; + if (chunkGraph.isModuleInChunk(module, chunk)) continue outer; } - return false; - }); + usedChunks.delete(chunk); + } - if (validChunks.length < usedChunks.length) { - if (isExistingChunk) validChunks.push(newChunk); - if (validChunks.length >= item.cacheGroup.minChunks) { + // Were some (invalid) chunks removed from usedChunks? + // => readd all modules to the queue, as things could have been changed + if (usedChunks.size < item.chunks.size) { + if (isExistingChunk) usedChunks.add(newChunk); + if (usedChunks.size >= item.cacheGroup.minChunks) { + const chunksArr = Array.from(usedChunks); for (const module of item.modules) { addModuleToChunksInfoMap( item.cacheGroup, - validChunks, - getKey(validChunks), + item.cacheGroupIndex, + chunksArr, + getKey(usedChunks), module ); } @@ -1071,13 +1102,19 @@ module.exports = class SplitChunksPlugin { // Validate minRemainingSize constraint when a single chunk is left over if ( - validChunks.length === 1 && - hasNonZeroSizes(item.cacheGroup.minRemainingSize) + !enforced && + item.cacheGroup._validateRemainingSize && + usedChunks.size === 1 ) { - const chunk = validChunks[0]; - const chunkSizes = { ...chunkGraph.getChunkModulesSizes(chunk) }; - for (const key of Object.keys(item.sizes)) { - chunkSizes[key] -= item.sizes[key]; + const [chunk] = usedChunks; + let chunkSizes = Object.create(null); + for (const module of chunkGraph.getChunkModulesIterable(chunk)) { + if (!item.modules.has(module)) { + for (const type of module.getSourceTypes()) { + chunkSizes[type] = + (chunkSizes[type] || 0) + module.size(type); + } + } } if (!checkMinSize(chunkSizes, item.cacheGroup.minRemainingSize)) { continue; @@ -1148,7 +1185,7 @@ module.exports = class SplitChunksPlugin { minSize: oldMaxSizeSettings ? combineSizes( oldMaxSizeSettings.minSize, - item.cacheGroup.minSizeForMaxSize, + item.cacheGroup._minSizeForMaxSize, Math.max ) : item.cacheGroup.minSize, @@ -1175,38 +1212,31 @@ module.exports = class SplitChunksPlugin { // remove all modules from other entries and update size for (const [key, info] of chunksInfoMap) { - if (isOverlap(info.chunks, item.chunks)) { - if (info.validateSize) { - // update modules and total size - // may remove it from the map when < minSize - let updated = false; - for (const module of item.modules) { - if (info.modules.has(module)) { - // remove module - info.modules.delete(module); - // update size - for (const key of module.getSourceTypes()) { - info.sizes[key] -= module.size(key); - } - updated = true; - } - } - if (updated) { - if (info.modules.size === 0) { - chunksInfoMap.delete(key); - continue; - } - if (!checkMinSize(info.sizes, info.cacheGroup.minSize)) { - chunksInfoMap.delete(key); - } - } - } else { - // only update the modules - for (const module of item.modules) { + if (isOverlap(info.chunks, usedChunks)) { + // update modules and total size + // may remove it from the map when < minSize + let updated = false; + for (const module of item.modules) { + if (info.modules.has(module)) { + // remove module info.modules.delete(module); + // update size + for (const key of module.getSourceTypes()) { + info.sizes[key] -= module.size(key); + } + updated = true; } + } + if (updated) { if (info.modules.size === 0) { chunksInfoMap.delete(key); + continue; + } + if ( + info.cacheGroup._validateSize && + !checkMinSize(info.sizes, info.cacheGroup.minSize) + ) { + chunksInfoMap.delete(key); } } } diff --git a/schemas/WebpackOptions.json b/schemas/WebpackOptions.json index bd29681fb..74455fe4e 100644 --- a/schemas/WebpackOptions.json +++ b/schemas/WebpackOptions.json @@ -1257,6 +1257,14 @@ "description": "Ignore minimum size, minimum chunks and maximum requests and always create chunks for this cache group.", "type": "boolean" }, + "enforceSizeThreshold": { + "description": "Size threshold at which splitting is enforced and other restrictions (minRemainingSize, maxAsyncRequests, maxInitialRequests) are ignored.", + "oneOf": [ + { + "$ref": "#/definitions/OptimizationSplitChunksSizes" + } + ] + }, "filename": { "description": "Sets the template for the filename for created chunks.", "anyOf": [ @@ -1464,6 +1472,14 @@ } ] }, + "enforceSizeThreshold": { + "description": "Size threshold at which splitting is enforced and other restrictions (minRemainingSize, maxAsyncRequests, maxInitialRequests) are ignored.", + "oneOf": [ + { + "$ref": "#/definitions/OptimizationSplitChunksSizes" + } + ] + }, "fallbackCacheGroup": { "description": "Options for modules not selected by any other cache group.", "type": "object", diff --git a/types.d.ts b/types.d.ts index e7202b110..8ab2381d6 100644 --- a/types.d.ts +++ b/types.d.ts @@ -430,6 +430,7 @@ declare interface CacheGroupSource { enforce?: boolean; minSize: Record; minRemainingSize: Record; + enforceSizeThreshold: Record; maxAsyncSize: Record; maxInitialSize: Record; minChunks?: number; @@ -4789,6 +4790,11 @@ declare interface OptimizationSplitChunksCacheGroup { */ enforce?: boolean; + /** + * Size threshold at which splitting is enforced and other restrictions (minRemainingSize, maxAsyncRequests, maxInitialRequests) are ignored. + */ + enforceSizeThreshold?: OptimizationSplitChunksSizes; + /** * Sets the template for the filename for created chunks. */ @@ -4891,6 +4897,11 @@ declare interface OptimizationSplitChunksOptions { */ chunks?: "initial" | "async" | "all" | ((chunk: Chunk) => boolean); + /** + * Size threshold at which splitting is enforced and other restrictions (minRemainingSize, maxAsyncRequests, maxInitialRequests) are ignored. + */ + enforceSizeThreshold?: OptimizationSplitChunksSizes; + /** * Options for modules not selected by any other cache group. */ @@ -7368,6 +7379,7 @@ declare interface SplitChunksOptions { chunksFilter: (chunk: Chunk) => boolean; minSize: Record; minRemainingSize: Record; + enforceSizeThreshold: Record; maxInitialSize: Record; maxAsyncSize: Record; minChunks: number; From b60fb2742a59c5def00bb7272f422b33f308b926 Mon Sep 17 00:00:00 2001 From: Tobias Koppers Date: Mon, 13 Jul 2020 10:13:27 +0200 Subject: [PATCH 2/4] adjust splitChunks defaults for http/2 --- lib/config/defaults.js | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/lib/config/defaults.js b/lib/config/defaults.js index b71877187..90f478735 100644 --- a/lib/config/defaults.js +++ b/lib/config/defaults.js @@ -580,11 +580,9 @@ const applyOptimizationDefaults = ( D(splitChunks, "hidePathInfo", production); D(splitChunks, "chunks", "async"); D(splitChunks, "minChunks", 1); - F(splitChunks, "minSize", () => (production ? 30000 : 10000)); + F(splitChunks, "minSize", () => (production ? 20000 : 10000)); F(splitChunks, "minRemainingSize", () => (development ? 0 : undefined)); - F(splitChunks, "enforceSizeThreshold", () => - production ? undefined : 100000 - ); + F(splitChunks, "enforceSizeThreshold", () => (production ? 50000 : 30000)); F(splitChunks, "maxAsyncRequests", () => (production ? 30 : Infinity)); F(splitChunks, "maxInitialRequests", () => (production ? 30 : Infinity)); D(splitChunks, "automaticNameDelimiter", "-"); From c537b6cf3ebb648241935afe29cde206ee71fe4c Mon Sep 17 00:00:00 2001 From: Tobias Koppers Date: Mon, 13 Jul 2020 10:28:48 +0200 Subject: [PATCH 3/4] add test case --- test/__snapshots__/StatsTestCases.test.js.snap | 11 +++++++++-- test/statsCases/split-chunks-keep-remaining-size/d.js | 3 +++ .../split-chunks-keep-remaining-size/index.js | 1 + .../webpack.config.js | 3 ++- 4 files changed, 15 insertions(+), 3 deletions(-) create mode 100644 test/statsCases/split-chunks-keep-remaining-size/d.js diff --git a/test/__snapshots__/StatsTestCases.test.js.snap b/test/__snapshots__/StatsTestCases.test.js.snap index 753d99637..6b23eebe9 100644 --- a/test/__snapshots__/StatsTestCases.test.js.snap +++ b/test/__snapshots__/StatsTestCases.test.js.snap @@ -3413,9 +3413,12 @@ chunk a.js (a) 12 bytes (javascript) 3.87 KiB (runtime) ={282}= [entry] [rendere exports[`StatsTestCases should print correct stats for split-chunks-keep-remaining-size 1`] = ` "Entrypoint main = default/main.js -chunk default/main.js (main) 147 bytes (javascript) 5.69 KiB (runtime) >{334}< >{383}< >{794}< >{821}< [entry] [rendered] +chunk default/async-d.js (async-d) 58 bytes <{179}> ={782}= [rendered] + > ./d ./index.js 4:0-47 + ./d.js 58 bytes [built] +chunk default/main.js (main) 196 bytes (javascript) 5.7 KiB (runtime) >{31}< >{334}< >{383}< >{782}< >{794}< >{821}< [entry] [rendered] > ./ main - ./index.js 147 bytes [built] + ./index.js 196 bytes [built] + 9 hidden chunk modules chunk default/async-b.js (async-b) 39 bytes <{179}> ={821}= [rendered] > ./b ./index.js 2:0-47 @@ -3423,6 +3426,10 @@ chunk default/async-b.js (async-b) 39 bytes <{179}> ={821}= [rendered] chunk default/async-c.js (async-c) 39 bytes <{179}> ={821}= [rendered] > ./c ./index.js 3:0-47 ./c.js 39 bytes [built] +chunk default/782.js (id hint: vendors) 204 bytes <{179}> ={31}= [rendered] split chunk (cache group: defaultVendors) + > ./d ./index.js 4:0-47 + ./node_modules/shared.js?3 102 bytes [built] + ./node_modules/shared.js?4 102 bytes [built] chunk default/async-a.js (async-a) 141 bytes <{179}> [rendered] > ./a ./index.js 1:0-47 ./a.js 39 bytes [built] diff --git a/test/statsCases/split-chunks-keep-remaining-size/d.js b/test/statsCases/split-chunks-keep-remaining-size/d.js new file mode 100644 index 000000000..1254c3522 --- /dev/null +++ b/test/statsCases/split-chunks-keep-remaining-size/d.js @@ -0,0 +1,3 @@ +import "shared?3"; +import "shared?4"; +export default "d"; diff --git a/test/statsCases/split-chunks-keep-remaining-size/index.js b/test/statsCases/split-chunks-keep-remaining-size/index.js index 5dfec91bc..685dfa4c0 100644 --- a/test/statsCases/split-chunks-keep-remaining-size/index.js +++ b/test/statsCases/split-chunks-keep-remaining-size/index.js @@ -1,3 +1,4 @@ import(/* webpackChunkName: "async-a" */ "./a"); import(/* webpackChunkName: "async-b" */ "./b"); import(/* webpackChunkName: "async-c" */ "./c"); +import(/* webpackChunkName: "async-d" */ "./d"); diff --git a/test/statsCases/split-chunks-keep-remaining-size/webpack.config.js b/test/statsCases/split-chunks-keep-remaining-size/webpack.config.js index eedc456bb..9f3d07326 100644 --- a/test/statsCases/split-chunks-keep-remaining-size/webpack.config.js +++ b/test/statsCases/split-chunks-keep-remaining-size/webpack.config.js @@ -21,7 +21,8 @@ module.exports = { }, optimization: { splitChunks: { - minSize: 100 + minSize: 100, + enforceSizeThreshold: 200 } }, stats From f1d84bcddedea3562a754a7a221f9c2ffc285e36 Mon Sep 17 00:00:00 2001 From: Tobias Koppers Date: Mon, 13 Jul 2020 13:45:57 +0200 Subject: [PATCH 4/4] update snapshots --- test/Defaults.unittest.js | 10 ++++++++-- test/Validation.test.js | 4 ++-- test/__snapshots__/Cli.test.js.snap | 13 +++++++++++++ 3 files changed, 23 insertions(+), 4 deletions(-) diff --git a/test/Defaults.unittest.js b/test/Defaults.unittest.js index eb3da94a5..664ef8303 100644 --- a/test/Defaults.unittest.js +++ b/test/Defaults.unittest.js @@ -184,6 +184,7 @@ describe("Defaults", () => { }, }, "chunks": "async", + "enforceSizeThreshold": 30000, "hidePathInfo": false, "maxAsyncRequests": Infinity, "maxInitialRequests": Infinity, @@ -379,15 +380,17 @@ describe("Defaults", () => { + "noEmitOnErrors": true, + "nodeEnv": "production", @@ ... @@ + - "enforceSizeThreshold": 30000, - "hidePathInfo": false, - "maxAsyncRequests": Infinity, - "maxInitialRequests": Infinity, + + "enforceSizeThreshold": 50000, + "hidePathInfo": true, + "maxAsyncRequests": 30, + "maxInitialRequests": 30, @@ ... @@ - "minSize": 10000, - + "minSize": 30000, + + "minSize": 20000, @@ ... @@ - "usedExports": false, + "usedExports": true, @@ -432,15 +435,17 @@ describe("Defaults", () => { + "noEmitOnErrors": true, + "nodeEnv": "production", @@ ... @@ + - "enforceSizeThreshold": 30000, - "hidePathInfo": false, - "maxAsyncRequests": Infinity, - "maxInitialRequests": Infinity, + + "enforceSizeThreshold": 50000, + "hidePathInfo": true, + "maxAsyncRequests": 30, + "maxInitialRequests": 30, @@ ... @@ - "minSize": 10000, - + "minSize": 30000, + + "minSize": 20000, @@ ... @@ - "usedExports": false, + "usedExports": true, @@ -956,6 +961,7 @@ describe("Defaults", () => { - }, - }, - "chunks": "async", + - "enforceSizeThreshold": 30000, - "hidePathInfo": false, - "maxAsyncRequests": Infinity, - "maxInitialRequests": Infinity, diff --git a/test/Validation.test.js b/test/Validation.test.js index ea1d0f013..aa7179b12 100644 --- a/test/Validation.test.js +++ b/test/Validation.test.js @@ -461,7 +461,7 @@ describe("Validation", () => { test: ... } }. - object { : false | RegExp | string | function | object { automaticNameDelimiter?, chunks?, enforce?, filename?, idHint?, maxAsyncRequests?, maxAsyncSize?, maxInitialRequests?, maxInitialSize?, maxSize?, minChunks?, minRemainingSize?, minSize?, name?, priority?, reuseExistingChunk?, test?, type? } } + object { : false | RegExp | string | function | object { automaticNameDelimiter?, chunks?, enforce?, enforceSizeThreshold?, filename?, idHint?, maxAsyncRequests?, maxAsyncSize?, maxInitialRequests?, maxInitialSize?, maxSize?, minChunks?, minRemainingSize?, minSize?, name?, priority?, reuseExistingChunk?, test?, type? } } -> Assign modules to a cache group (modules from different cache groups are tried to keep in separate chunks, default categories: 'default', 'defaultVendors')." `) ); @@ -715,7 +715,7 @@ describe("Validation", () => { expect(msg).toMatchInlineSnapshot(` "Invalid configuration object. Webpack has been initialized using a configuration object that does not match the API schema. - configuration.optimization.splitChunks has an unknown property 'automaticNamePrefix'. These properties are valid: - object { automaticNameDelimiter?, cacheGroups?, chunks?, fallbackCacheGroup?, filename?, hidePathInfo?, maxAsyncRequests?, maxAsyncSize?, maxInitialRequests?, maxInitialSize?, maxSize?, minChunks?, minRemainingSize?, minSize?, name? } + object { automaticNameDelimiter?, cacheGroups?, chunks?, enforceSizeThreshold?, fallbackCacheGroup?, filename?, hidePathInfo?, maxAsyncRequests?, maxAsyncSize?, maxInitialRequests?, maxInitialSize?, maxSize?, minChunks?, minRemainingSize?, minSize?, name? } -> Options object for splitting chunks into smaller chunks." `) ); diff --git a/test/__snapshots__/Cli.test.js.snap b/test/__snapshots__/Cli.test.js.snap index 91e6fc195..f30c10707 100644 --- a/test/__snapshots__/Cli.test.js.snap +++ b/test/__snapshots__/Cli.test.js.snap @@ -1532,6 +1532,19 @@ Object { "multiple": false, "simpleType": "string", }, + "optimization-split-chunks-enforce-size-threshold": Object { + "configs": Array [ + Object { + "description": "Size of the javascript part of the chunk.", + "multiple": false, + "path": "optimization.splitChunks.enforceSizeThreshold", + "type": "number", + }, + ], + "description": "Size of the javascript part of the chunk.", + "multiple": false, + "simpleType": "number", + }, "optimization-split-chunks-fallback-cache-group-automatic-name-delimiter": Object { "configs": Array [ Object {