| 
									
										
										
										
											2018-01-20 00:06:59 +08:00
										 |  |  | /* | 
					
						
							|  |  |  | 	MIT License http://www.opensource.org/licenses/mit-license.php
 | 
					
						
							|  |  |  | 	Author Tobias Koppers @sokra | 
					
						
							|  |  |  | */ | 
					
						
							| 
									
										
										
										
											2018-07-30 23:08:51 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-20 00:06:59 +08:00
										 |  |  | "use strict"; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-08 21:08:48 +08:00
										 |  |  | const Chunk = require("../Chunk"); | 
					
						
							| 
									
										
										
										
											2018-07-31 04:30:27 +08:00
										 |  |  | const { STAGE_ADVANCED } = require("../OptimizationStages"); | 
					
						
							| 
									
										
										
										
											2018-08-25 03:06:52 +08:00
										 |  |  | const WebpackError = require("../WebpackError"); | 
					
						
							| 
									
										
										
										
											2018-12-07 19:26:35 +08:00
										 |  |  | const { requestToId } = require("../ids/IdHelpers"); | 
					
						
							| 
									
										
										
										
											2021-10-08 21:08:48 +08:00
										 |  |  | const { isSubset } = require("../util/SetHelpers"); | 
					
						
							| 
									
										
										
										
											2018-07-30 23:08:51 +08:00
										 |  |  | const SortableSet = require("../util/SortableSet"); | 
					
						
							| 
									
										
										
										
											2018-08-28 21:07:28 +08:00
										 |  |  | const { | 
					
						
							|  |  |  | 	compareModulesByIdentifier, | 
					
						
							|  |  |  | 	compareIterables | 
					
						
							|  |  |  | } = require("../util/comparators"); | 
					
						
							| 
									
										
										
										
											2020-01-31 19:18:55 +08:00
										 |  |  | const createHash = require("../util/createHash"); | 
					
						
							| 
									
										
										
										
											2018-07-04 15:59:22 +08:00
										 |  |  | const deterministicGrouping = require("../util/deterministicGrouping"); | 
					
						
							| 
									
										
										
										
											2021-08-06 17:50:55 +08:00
										 |  |  | const { makePathsRelative } = require("../util/identifier"); | 
					
						
							| 
									
										
										
										
											2020-12-27 05:32:57 +08:00
										 |  |  | const memoize = require("../util/memoize"); | 
					
						
							| 
									
										
										
										
											2018-12-04 18:02:26 +08:00
										 |  |  | const MinMaxSizeWarning = require("./MinMaxSizeWarning"); | 
					
						
							| 
									
										
										
										
											2018-01-20 00:06:59 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-11 04:19:10 +08:00
										 |  |  | /** @typedef {import("../../declarations/WebpackOptions").OptimizationSplitChunksCacheGroup} OptimizationSplitChunksCacheGroup */ | 
					
						
							| 
									
										
										
										
											2018-12-12 17:46:44 +08:00
										 |  |  | /** @typedef {import("../../declarations/WebpackOptions").OptimizationSplitChunksGetCacheGroups} OptimizationSplitChunksGetCacheGroups */ | 
					
						
							| 
									
										
										
										
											2018-12-11 04:19:10 +08:00
										 |  |  | /** @typedef {import("../../declarations/WebpackOptions").OptimizationSplitChunksOptions} OptimizationSplitChunksOptions */ | 
					
						
							|  |  |  | /** @typedef {import("../../declarations/WebpackOptions").OptimizationSplitChunksSizes} OptimizationSplitChunksSizes */ | 
					
						
							| 
									
										
										
										
											2020-02-17 17:27:46 +08:00
										 |  |  | /** @typedef {import("../../declarations/WebpackOptions").Output} OutputOptions */ | 
					
						
							| 
									
										
										
										
											2018-08-14 17:18:22 +08:00
										 |  |  | /** @typedef {import("../ChunkGraph")} ChunkGraph */ | 
					
						
							| 
									
										
										
										
											2020-09-25 15:51:30 +08:00
										 |  |  | /** @typedef {import("../ChunkGroup")} ChunkGroup */ | 
					
						
							| 
									
										
										
										
											2019-09-13 17:12:26 +08:00
										 |  |  | /** @typedef {import("../Compilation").AssetInfo} AssetInfo */ | 
					
						
							| 
									
										
										
										
											2019-06-19 04:09:10 +08:00
										 |  |  | /** @typedef {import("../Compilation").PathData} PathData */ | 
					
						
							| 
									
										
										
										
											2018-08-14 17:18:06 +08:00
										 |  |  | /** @typedef {import("../Compiler")} Compiler */ | 
					
						
							| 
									
										
										
										
											2018-05-17 18:35:13 +08:00
										 |  |  | /** @typedef {import("../Module")} Module */ | 
					
						
							| 
									
										
										
										
											2018-08-14 17:18:22 +08:00
										 |  |  | /** @typedef {import("../ModuleGraph")} ModuleGraph */ | 
					
						
							| 
									
										
										
										
											2018-07-04 15:59:22 +08:00
										 |  |  | /** @typedef {import("../util/deterministicGrouping").GroupedItems<Module>} DeterministicGroupingGroupedItemsForModule */ | 
					
						
							| 
									
										
										
										
											2018-08-14 17:18:06 +08:00
										 |  |  | /** @typedef {import("../util/deterministicGrouping").Options<Module>} DeterministicGroupingOptionsForModule */ | 
					
						
							| 
									
										
										
										
											2018-07-04 15:59:22 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-11 04:19:10 +08:00
										 |  |  | /** @typedef {Record<string, number>} SplitChunksSizes */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /** | 
					
						
							|  |  |  |  * @callback ChunkFilterFunction | 
					
						
							|  |  |  |  * @param {Chunk} chunk | 
					
						
							|  |  |  |  * @returns {boolean} | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-12 03:47:50 +08:00
										 |  |  | /** | 
					
						
							|  |  |  |  * @callback CombineSizeFunction | 
					
						
							|  |  |  |  * @param {number} a | 
					
						
							|  |  |  |  * @param {number} b | 
					
						
							|  |  |  |  * @returns {number} | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-11 04:19:10 +08:00
										 |  |  | /** | 
					
						
							|  |  |  |  * @typedef {Object} CacheGroupSource | 
					
						
							|  |  |  |  * @property {string=} key | 
					
						
							|  |  |  |  * @property {number=} priority | 
					
						
							|  |  |  |  * @property {GetName=} getName | 
					
						
							|  |  |  |  * @property {ChunkFilterFunction=} chunksFilter | 
					
						
							|  |  |  |  * @property {boolean=} enforce | 
					
						
							|  |  |  |  * @property {SplitChunksSizes} minSize | 
					
						
							| 
									
										
										
										
											2021-10-19 15:42:57 +08:00
										 |  |  |  * @property {SplitChunksSizes} minSizeReduction | 
					
						
							| 
									
										
										
										
											2019-05-13 19:10:23 +08:00
										 |  |  |  * @property {SplitChunksSizes} minRemainingSize | 
					
						
							| 
									
										
										
										
											2020-07-13 16:12:17 +08:00
										 |  |  |  * @property {SplitChunksSizes} enforceSizeThreshold | 
					
						
							| 
									
										
										
										
											2018-12-12 03:47:50 +08:00
										 |  |  |  * @property {SplitChunksSizes} maxAsyncSize | 
					
						
							|  |  |  |  * @property {SplitChunksSizes} maxInitialSize | 
					
						
							| 
									
										
										
										
											2018-12-11 04:19:10 +08:00
										 |  |  |  * @property {number=} minChunks | 
					
						
							|  |  |  |  * @property {number=} maxAsyncRequests | 
					
						
							|  |  |  |  * @property {number=} maxInitialRequests | 
					
						
							| 
									
										
										
										
											2019-09-13 17:12:26 +08:00
										 |  |  |  * @property {(string | function(PathData, AssetInfo=): string)=} filename | 
					
						
							| 
									
										
										
										
											2018-12-11 04:19:10 +08:00
										 |  |  |  * @property {string=} idHint | 
					
						
							|  |  |  |  * @property {string} automaticNameDelimiter | 
					
						
							|  |  |  |  * @property {boolean=} reuseExistingChunk | 
					
						
							| 
									
										
										
										
											2020-07-28 00:09:48 +08:00
										 |  |  |  * @property {boolean=} usedExports | 
					
						
							| 
									
										
										
										
											2018-12-11 04:19:10 +08:00
										 |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /** | 
					
						
							|  |  |  |  * @typedef {Object} CacheGroup | 
					
						
							|  |  |  |  * @property {string} key | 
					
						
							|  |  |  |  * @property {number=} priority | 
					
						
							|  |  |  |  * @property {GetName=} getName | 
					
						
							|  |  |  |  * @property {ChunkFilterFunction=} chunksFilter | 
					
						
							|  |  |  |  * @property {SplitChunksSizes} minSize | 
					
						
							| 
									
										
										
										
											2021-10-19 15:42:57 +08:00
										 |  |  |  * @property {SplitChunksSizes} minSizeReduction | 
					
						
							| 
									
										
										
										
											2019-05-13 19:10:23 +08:00
										 |  |  |  * @property {SplitChunksSizes} minRemainingSize | 
					
						
							| 
									
										
										
										
											2020-07-13 16:12:17 +08:00
										 |  |  |  * @property {SplitChunksSizes} enforceSizeThreshold | 
					
						
							| 
									
										
										
										
											2018-12-11 04:19:10 +08:00
										 |  |  |  * @property {SplitChunksSizes} maxAsyncSize | 
					
						
							|  |  |  |  * @property {SplitChunksSizes} maxInitialSize | 
					
						
							|  |  |  |  * @property {number=} minChunks | 
					
						
							|  |  |  |  * @property {number=} maxAsyncRequests | 
					
						
							|  |  |  |  * @property {number=} maxInitialRequests | 
					
						
							| 
									
										
										
										
											2019-09-13 17:12:26 +08:00
										 |  |  |  * @property {(string | function(PathData, AssetInfo=): string)=} filename | 
					
						
							| 
									
										
										
										
											2018-12-11 04:19:10 +08:00
										 |  |  |  * @property {string=} idHint | 
					
						
							|  |  |  |  * @property {string} automaticNameDelimiter | 
					
						
							| 
									
										
										
										
											2020-07-28 00:09:48 +08:00
										 |  |  |  * @property {boolean} reuseExistingChunk | 
					
						
							|  |  |  |  * @property {boolean} usedExports | 
					
						
							| 
									
										
										
										
											2020-07-13 16:12:17 +08:00
										 |  |  |  * @property {boolean} _validateSize | 
					
						
							|  |  |  |  * @property {boolean} _validateRemainingSize | 
					
						
							|  |  |  |  * @property {SplitChunksSizes} _minSizeForMaxSize | 
					
						
							|  |  |  |  * @property {boolean} _conditionalEnforce | 
					
						
							| 
									
										
										
										
											2018-12-11 04:19:10 +08:00
										 |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /** | 
					
						
							|  |  |  |  * @typedef {Object} FallbackCacheGroup | 
					
						
							| 
									
										
										
										
											2021-11-02 20:23:09 +08:00
										 |  |  |  * @property {ChunkFilterFunction} chunksFilter | 
					
						
							| 
									
										
										
										
											2018-12-11 04:19:10 +08:00
										 |  |  |  * @property {SplitChunksSizes} minSize | 
					
						
							| 
									
										
										
										
											2018-12-12 03:47:50 +08:00
										 |  |  |  * @property {SplitChunksSizes} maxAsyncSize | 
					
						
							|  |  |  |  * @property {SplitChunksSizes} maxInitialSize | 
					
						
							| 
									
										
										
										
											2018-12-11 04:19:10 +08:00
										 |  |  |  * @property {string} automaticNameDelimiter | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /** | 
					
						
							|  |  |  |  * @typedef {Object} CacheGroupsContext | 
					
						
							|  |  |  |  * @property {ModuleGraph} moduleGraph | 
					
						
							|  |  |  |  * @property {ChunkGraph} chunkGraph | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /** | 
					
						
							|  |  |  |  * @callback GetCacheGroups | 
					
						
							|  |  |  |  * @param {Module} module | 
					
						
							|  |  |  |  * @param {CacheGroupsContext} context | 
					
						
							|  |  |  |  * @returns {CacheGroupSource[]} | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /** | 
					
						
							|  |  |  |  * @callback GetName | 
					
						
							|  |  |  |  * @param {Module=} module | 
					
						
							| 
									
										
										
										
											2018-12-12 17:46:44 +08:00
										 |  |  |  * @param {Chunk[]=} chunks | 
					
						
							| 
									
										
										
										
											2018-12-11 04:19:10 +08:00
										 |  |  |  * @param {string=} key | 
					
						
							|  |  |  |  * @returns {string=} | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /** | 
					
						
							|  |  |  |  * @typedef {Object} SplitChunksOptions | 
					
						
							|  |  |  |  * @property {ChunkFilterFunction} chunksFilter | 
					
						
							| 
									
										
										
										
											2020-09-29 17:16:24 +08:00
										 |  |  |  * @property {string[]} defaultSizeTypes | 
					
						
							| 
									
										
										
										
											2018-12-11 04:19:10 +08:00
										 |  |  |  * @property {SplitChunksSizes} minSize | 
					
						
							| 
									
										
										
										
											2021-10-19 15:42:57 +08:00
										 |  |  |  * @property {SplitChunksSizes} minSizeReduction | 
					
						
							| 
									
										
										
										
											2019-05-13 19:10:23 +08:00
										 |  |  |  * @property {SplitChunksSizes} minRemainingSize | 
					
						
							| 
									
										
										
										
											2020-07-13 16:12:17 +08:00
										 |  |  |  * @property {SplitChunksSizes} enforceSizeThreshold | 
					
						
							| 
									
										
										
										
											2018-12-11 04:19:10 +08:00
										 |  |  |  * @property {SplitChunksSizes} maxInitialSize | 
					
						
							|  |  |  |  * @property {SplitChunksSizes} maxAsyncSize | 
					
						
							|  |  |  |  * @property {number} minChunks | 
					
						
							|  |  |  |  * @property {number} maxAsyncRequests | 
					
						
							|  |  |  |  * @property {number} maxInitialRequests | 
					
						
							|  |  |  |  * @property {boolean} hidePathInfo | 
					
						
							| 
									
										
										
										
											2019-09-13 17:12:26 +08:00
										 |  |  |  * @property {string | function(PathData, AssetInfo=): string} filename | 
					
						
							| 
									
										
										
										
											2018-12-11 04:19:10 +08:00
										 |  |  |  * @property {string} automaticNameDelimiter | 
					
						
							|  |  |  |  * @property {GetCacheGroups} getCacheGroups | 
					
						
							|  |  |  |  * @property {GetName} getName | 
					
						
							| 
									
										
										
										
											2020-07-28 00:09:48 +08:00
										 |  |  |  * @property {boolean} usedExports | 
					
						
							| 
									
										
										
										
											2018-12-11 04:19:10 +08:00
										 |  |  |  * @property {FallbackCacheGroup} fallbackCacheGroup | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-08-28 17:50:33 +08:00
										 |  |  | /** | 
					
						
							|  |  |  |  * @typedef {Object} ChunksInfoItem | 
					
						
							| 
									
										
										
										
											2018-12-05 22:49:00 +08:00
										 |  |  |  * @property {SortableSet<Module>} modules | 
					
						
							| 
									
										
										
										
											2018-12-11 04:19:10 +08:00
										 |  |  |  * @property {CacheGroup} cacheGroup | 
					
						
							| 
									
										
										
										
											2020-07-13 16:12:17 +08:00
										 |  |  |  * @property {number} cacheGroupIndex | 
					
						
							| 
									
										
										
										
											2018-08-28 17:50:33 +08:00
										 |  |  |  * @property {string} name | 
					
						
							| 
									
										
										
										
											2018-12-04 23:40:06 +08:00
										 |  |  |  * @property {Record<string, number>} sizes | 
					
						
							| 
									
										
										
										
											2021-10-08 21:08:48 +08:00
										 |  |  |  * @property {Set<Chunk>} chunks | 
					
						
							| 
									
										
										
										
											2018-08-28 17:50:33 +08:00
										 |  |  |  * @property {Set<Chunk>} reuseableChunks | 
					
						
							| 
									
										
										
										
											2021-10-08 21:08:48 +08:00
										 |  |  |  * @property {Set<bigint | Chunk>} chunksKeys | 
					
						
							| 
									
										
										
										
											2018-08-28 17:50:33 +08:00
										 |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-11 04:19:10 +08:00
										 |  |  | const defaultGetName = /** @type {GetName} */ (() => {}); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-11 15:31:46 +08:00
										 |  |  | const deterministicGroupingForModules = | 
					
						
							|  |  |  | 	/** @type {function(DeterministicGroupingOptionsForModule): DeterministicGroupingGroupedItemsForModule[]} */ ( | 
					
						
							|  |  |  | 		deterministicGrouping | 
					
						
							|  |  |  | 	); | 
					
						
							| 
									
										
										
										
											2018-04-27 20:29:34 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-31 19:18:55 +08:00
										 |  |  | /** @type {WeakMap<Module, string>} */ | 
					
						
							|  |  |  | const getKeyCache = new WeakMap(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-11 04:19:10 +08:00
										 |  |  | /** | 
					
						
							|  |  |  |  * @param {string} name a filename to hash | 
					
						
							| 
									
										
										
										
											2020-02-04 16:18:54 +08:00
										 |  |  |  * @param {OutputOptions} outputOptions hash function used | 
					
						
							| 
									
										
										
										
											2018-12-11 04:19:10 +08:00
										 |  |  |  * @returns {string} hashed filename | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2020-02-04 16:18:54 +08:00
										 |  |  | const hashFilename = (name, outputOptions) => { | 
					
						
							| 
									
										
										
										
											2021-05-11 15:31:46 +08:00
										 |  |  | 	const digest = /** @type {string} */ ( | 
					
						
							|  |  |  | 		createHash(outputOptions.hashFunction) | 
					
						
							|  |  |  | 			.update(name) | 
					
						
							|  |  |  | 			.digest(outputOptions.hashDigest) | 
					
						
							|  |  |  | 	); | 
					
						
							| 
									
										
										
										
											2020-01-31 19:18:55 +08:00
										 |  |  | 	return digest.slice(0, 8); | 
					
						
							| 
									
										
										
										
											2018-02-01 02:52:50 +08:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-11 04:19:10 +08:00
										 |  |  | /** | 
					
						
							|  |  |  |  * @param {Chunk} chunk the chunk | 
					
						
							|  |  |  |  * @returns {number} the number of requests | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2018-01-20 00:06:59 +08:00
										 |  |  | const getRequests = chunk => { | 
					
						
							|  |  |  | 	let requests = 0; | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 	for (const chunkGroup of chunk.groupsIterable) { | 
					
						
							| 
									
										
										
										
											2018-01-20 00:06:59 +08:00
										 |  |  | 		requests = Math.max(requests, chunkGroup.chunks.length); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return requests; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-20 21:41:39 +08:00
										 |  |  | const mapObject = (obj, fn) => { | 
					
						
							|  |  |  | 	const newObj = Object.create(null); | 
					
						
							|  |  |  | 	for (const key of Object.keys(obj)) { | 
					
						
							|  |  |  | 		newObj[key] = fn(obj[key], key); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return newObj; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-08 21:08:48 +08:00
										 |  |  | /** | 
					
						
							|  |  |  |  * @template T | 
					
						
							|  |  |  |  * @param {Set<T>} a set | 
					
						
							|  |  |  |  * @param {Set<T>} b other set | 
					
						
							|  |  |  |  * @returns {boolean} true if at least one item of a is in b | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | const isOverlap = (a, b) => { | 
					
						
							|  |  |  | 	for (const item of a) { | 
					
						
							|  |  |  | 		if (b.has(item)) return true; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return false; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-08-28 21:07:28 +08:00
										 |  |  | const compareModuleIterables = compareIterables(compareModulesByIdentifier); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-08-28 17:50:33 +08:00
										 |  |  | /** | 
					
						
							|  |  |  |  * @param {ChunksInfoItem} a item | 
					
						
							|  |  |  |  * @param {ChunksInfoItem} b item | 
					
						
							|  |  |  |  * @returns {number} compare result | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2018-01-20 00:06:59 +08:00
										 |  |  | const compareEntries = (a, b) => { | 
					
						
							| 
									
										
										
										
											2018-01-20 20:11:02 +08:00
										 |  |  | 	// 1. by priority
 | 
					
						
							|  |  |  | 	const diffPriority = a.cacheGroup.priority - b.cacheGroup.priority; | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 	if (diffPriority) return diffPriority; | 
					
						
							| 
									
										
										
										
											2018-02-16 16:12:01 +08:00
										 |  |  | 	// 2. by number of chunks
 | 
					
						
							|  |  |  | 	const diffCount = a.chunks.size - b.chunks.size; | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 	if (diffCount) return diffCount; | 
					
						
							| 
									
										
										
										
											2018-02-16 16:12:01 +08:00
										 |  |  | 	// 3. by size reduction
 | 
					
						
							| 
									
										
										
										
											2018-12-04 23:40:06 +08:00
										 |  |  | 	const aSizeReduce = totalSize(a.sizes) * (a.chunks.size - 1); | 
					
						
							|  |  |  | 	const bSizeReduce = totalSize(b.sizes) * (b.chunks.size - 1); | 
					
						
							| 
									
										
										
										
											2018-02-16 16:12:01 +08:00
										 |  |  | 	const diffSizeReduce = aSizeReduce - bSizeReduce; | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 	if (diffSizeReduce) return diffSizeReduce; | 
					
						
							| 
									
										
										
										
											2020-07-13 16:12:17 +08:00
										 |  |  | 	// 4. by cache group index
 | 
					
						
							| 
									
										
										
										
											2021-01-08 04:47:08 +08:00
										 |  |  | 	const indexDiff = b.cacheGroupIndex - a.cacheGroupIndex; | 
					
						
							| 
									
										
										
										
											2020-07-13 16:12:17 +08:00
										 |  |  | 	if (indexDiff) return indexDiff; | 
					
						
							|  |  |  | 	// 5. by number of modules (to be able to compare by identifier)
 | 
					
						
							| 
									
										
										
										
											2018-01-20 00:06:59 +08:00
										 |  |  | 	const modulesA = a.modules; | 
					
						
							|  |  |  | 	const modulesB = b.modules; | 
					
						
							|  |  |  | 	const diff = modulesA.size - modulesB.size; | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 	if (diff) return diff; | 
					
						
							| 
									
										
										
										
											2020-07-13 16:12:17 +08:00
										 |  |  | 	// 6. by module identifiers
 | 
					
						
							| 
									
										
										
										
											2018-01-20 00:06:59 +08:00
										 |  |  | 	modulesA.sort(); | 
					
						
							|  |  |  | 	modulesB.sort(); | 
					
						
							| 
									
										
										
										
											2019-06-14 16:45:56 +08:00
										 |  |  | 	return compareModuleIterables(modulesA, modulesB); | 
					
						
							| 
									
										
										
										
											2018-01-20 00:06:59 +08:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-04-27 20:29:34 +08:00
										 |  |  | const INITIAL_CHUNK_FILTER = chunk => chunk.canBeInitial(); | 
					
						
							|  |  |  | const ASYNC_CHUNK_FILTER = chunk => !chunk.canBeInitial(); | 
					
						
							|  |  |  | const ALL_CHUNK_FILTER = chunk => true; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-11 04:19:10 +08:00
										 |  |  | /** | 
					
						
							|  |  |  |  * @param {OptimizationSplitChunksSizes} value the sizes | 
					
						
							| 
									
										
										
										
											2020-09-29 17:16:24 +08:00
										 |  |  |  * @param {string[]} defaultSizeTypes the default size types | 
					
						
							| 
									
										
										
										
											2018-12-11 04:19:10 +08:00
										 |  |  |  * @returns {SplitChunksSizes} normalized representation | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2020-09-29 17:16:24 +08:00
										 |  |  | const normalizeSizes = (value, defaultSizeTypes) => { | 
					
						
							| 
									
										
										
										
											2018-12-04 23:40:06 +08:00
										 |  |  | 	if (typeof value === "number") { | 
					
						
							| 
									
										
										
										
											2020-09-29 17:16:24 +08:00
										 |  |  | 		/** @type {Record<string, number>} */ | 
					
						
							|  |  |  | 		const o = {}; | 
					
						
							|  |  |  | 		for (const sizeType of defaultSizeTypes) o[sizeType] = value; | 
					
						
							|  |  |  | 		return o; | 
					
						
							| 
									
										
										
										
											2018-12-11 04:19:10 +08:00
										 |  |  | 	} else if (typeof value === "object" && value !== null) { | 
					
						
							| 
									
										
										
										
											2019-06-19 19:16:05 +08:00
										 |  |  | 		return { ...value }; | 
					
						
							| 
									
										
										
										
											2018-12-04 23:40:06 +08:00
										 |  |  | 	} else { | 
					
						
							| 
									
										
										
										
											2018-12-12 03:47:50 +08:00
										 |  |  | 		return {}; | 
					
						
							| 
									
										
										
										
											2018-12-04 23:40:06 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-11 04:19:10 +08:00
										 |  |  | /** | 
					
						
							| 
									
										
										
										
											2020-09-29 17:16:24 +08:00
										 |  |  |  * @param {...SplitChunksSizes} sizes the sizes | 
					
						
							| 
									
										
										
										
											2018-12-11 04:19:10 +08:00
										 |  |  |  * @returns {SplitChunksSizes} the merged sizes | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2018-12-12 03:47:50 +08:00
										 |  |  | const mergeSizes = (...sizes) => { | 
					
						
							| 
									
										
										
										
											2019-07-10 02:49:10 +08:00
										 |  |  | 	/** @type {SplitChunksSizes} */ | 
					
						
							|  |  |  | 	let merged = {}; | 
					
						
							|  |  |  | 	for (let i = sizes.length - 1; i >= 0; i--) { | 
					
						
							| 
									
										
										
										
											2020-09-29 17:16:24 +08:00
										 |  |  | 		merged = Object.assign(merged, sizes[i]); | 
					
						
							| 
									
										
										
										
											2019-07-10 02:49:10 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	return merged; | 
					
						
							| 
									
										
										
										
											2018-12-04 23:40:06 +08:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-13 19:10:23 +08:00
										 |  |  | /** | 
					
						
							|  |  |  |  * @param {SplitChunksSizes} sizes the sizes | 
					
						
							|  |  |  |  * @returns {boolean} true, if there are sizes > 0 | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | const hasNonZeroSizes = sizes => { | 
					
						
							|  |  |  | 	for (const key of Object.keys(sizes)) { | 
					
						
							|  |  |  | 		if (sizes[key] > 0) return true; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return false; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-12 03:47:50 +08:00
										 |  |  | /** | 
					
						
							|  |  |  |  * @param {SplitChunksSizes} a first sizes | 
					
						
							|  |  |  |  * @param {SplitChunksSizes} b second sizes | 
					
						
							|  |  |  |  * @param {CombineSizeFunction} combine a function to combine sizes | 
					
						
							|  |  |  |  * @returns {SplitChunksSizes} the combine sizes | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2018-12-04 23:40:06 +08:00
										 |  |  | const combineSizes = (a, b, combine) => { | 
					
						
							|  |  |  | 	const aKeys = new Set(Object.keys(a)); | 
					
						
							|  |  |  | 	const bKeys = new Set(Object.keys(b)); | 
					
						
							| 
									
										
										
										
											2018-12-12 03:47:50 +08:00
										 |  |  | 	/** @type {SplitChunksSizes} */ | 
					
						
							|  |  |  | 	const result = {}; | 
					
						
							| 
									
										
										
										
											2018-12-04 23:40:06 +08:00
										 |  |  | 	for (const key of aKeys) { | 
					
						
							|  |  |  | 		if (bKeys.has(key)) { | 
					
						
							|  |  |  | 			result[key] = combine(a[key], b[key]); | 
					
						
							|  |  |  | 		} else { | 
					
						
							|  |  |  | 			result[key] = a[key]; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	for (const key of bKeys) { | 
					
						
							|  |  |  | 		if (!aKeys.has(key)) { | 
					
						
							|  |  |  | 			result[key] = b[key]; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return result; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-11 04:19:10 +08:00
										 |  |  | /** | 
					
						
							|  |  |  |  * @param {SplitChunksSizes} sizes the sizes | 
					
						
							|  |  |  |  * @param {SplitChunksSizes} minSize the min sizes | 
					
						
							| 
									
										
										
										
											2019-05-13 19:10:23 +08:00
										 |  |  |  * @returns {boolean} true if there are sizes and all existing sizes are at least `minSize` | 
					
						
							| 
									
										
										
										
											2018-12-11 04:19:10 +08:00
										 |  |  |  */ | 
					
						
							| 
									
										
										
										
											2018-12-04 23:40:06 +08:00
										 |  |  | const checkMinSize = (sizes, minSize) => { | 
					
						
							|  |  |  | 	for (const key of Object.keys(minSize)) { | 
					
						
							|  |  |  | 		const size = sizes[key]; | 
					
						
							| 
									
										
										
										
											2019-05-13 19:10:23 +08:00
										 |  |  | 		if (size === undefined || size === 0) continue; | 
					
						
							| 
									
										
										
										
											2018-12-04 23:40:06 +08:00
										 |  |  | 		if (size < minSize[key]) return false; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return true; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-19 15:42:57 +08:00
										 |  |  | /** | 
					
						
							|  |  |  |  * @param {SplitChunksSizes} sizes the sizes | 
					
						
							|  |  |  |  * @param {SplitChunksSizes} minSizeReduction the min sizes | 
					
						
							|  |  |  |  * @param {number} chunkCount number of chunks | 
					
						
							|  |  |  |  * @returns {boolean} true if there are sizes and all existing sizes are at least `minSizeReduction` | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | const checkMinSizeReduction = (sizes, minSizeReduction, chunkCount) => { | 
					
						
							|  |  |  | 	for (const key of Object.keys(minSizeReduction)) { | 
					
						
							|  |  |  | 		const size = sizes[key]; | 
					
						
							|  |  |  | 		if (size === undefined || size === 0) continue; | 
					
						
							|  |  |  | 		if (size * chunkCount < minSizeReduction[key]) return false; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return true; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-25 22:16:05 +08:00
										 |  |  | /** | 
					
						
							|  |  |  |  * @param {SplitChunksSizes} sizes the sizes | 
					
						
							|  |  |  |  * @param {SplitChunksSizes} minSize the min sizes | 
					
						
							|  |  |  |  * @returns {undefined | string[]} list of size types that are below min size | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | const getViolatingMinSizes = (sizes, minSize) => { | 
					
						
							|  |  |  | 	let list; | 
					
						
							|  |  |  | 	for (const key of Object.keys(minSize)) { | 
					
						
							|  |  |  | 		const size = sizes[key]; | 
					
						
							|  |  |  | 		if (size === undefined || size === 0) continue; | 
					
						
							|  |  |  | 		if (size < minSize[key]) { | 
					
						
							|  |  |  | 			if (list === undefined) list = [key]; | 
					
						
							|  |  |  | 			else list.push(key); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return list; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-11 04:19:10 +08:00
										 |  |  | /** | 
					
						
							|  |  |  |  * @param {SplitChunksSizes} sizes the sizes | 
					
						
							|  |  |  |  * @returns {number} the total size | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2018-12-04 23:40:06 +08:00
										 |  |  | const totalSize = sizes => { | 
					
						
							|  |  |  | 	let size = 0; | 
					
						
							|  |  |  | 	for (const key of Object.keys(sizes)) { | 
					
						
							|  |  |  | 		size += sizes[key]; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return size; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-11 04:19:10 +08:00
										 |  |  | /** | 
					
						
							|  |  |  |  * @param {false|string|Function} name the chunk name | 
					
						
							|  |  |  |  * @returns {GetName} a function to get the name of the chunk | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | const normalizeName = name => { | 
					
						
							|  |  |  | 	if (typeof name === "string") { | 
					
						
							|  |  |  | 		return () => name; | 
					
						
							| 
									
										
										
										
											2018-01-20 00:06:59 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2018-12-11 04:19:10 +08:00
										 |  |  | 	if (typeof name === "function") { | 
					
						
							|  |  |  | 		return /** @type {GetName} */ (name); | 
					
						
							| 
									
										
										
										
											2018-01-20 00:06:59 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2018-12-11 04:19:10 +08:00
										 |  |  | }; | 
					
						
							| 
									
										
										
										
											2018-01-20 00:06:59 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-11 04:19:10 +08:00
										 |  |  | /** | 
					
						
							| 
									
										
										
										
											2020-04-20 15:23:10 +08:00
										 |  |  |  * @param {OptimizationSplitChunksCacheGroup["chunks"]} chunks the chunk filter option | 
					
						
							| 
									
										
										
										
											2018-12-11 04:19:10 +08:00
										 |  |  |  * @returns {ChunkFilterFunction} the chunk filter function | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | const normalizeChunksFilter = chunks => { | 
					
						
							|  |  |  | 	if (chunks === "initial") { | 
					
						
							|  |  |  | 		return INITIAL_CHUNK_FILTER; | 
					
						
							| 
									
										
										
										
											2018-01-20 00:06:59 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2018-12-11 04:19:10 +08:00
										 |  |  | 	if (chunks === "async") { | 
					
						
							|  |  |  | 		return ASYNC_CHUNK_FILTER; | 
					
						
							| 
									
										
										
										
											2018-03-20 20:18:09 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2018-12-11 04:19:10 +08:00
										 |  |  | 	if (chunks === "all") { | 
					
						
							|  |  |  | 		return ALL_CHUNK_FILTER; | 
					
						
							| 
									
										
										
										
											2018-07-04 15:59:22 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2018-12-11 04:19:10 +08:00
										 |  |  | 	if (typeof chunks === "function") { | 
					
						
							| 
									
										
										
										
											2020-04-20 15:23:10 +08:00
										 |  |  | 		return chunks; | 
					
						
							| 
									
										
										
										
											2018-12-11 04:19:10 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | }; | 
					
						
							| 
									
										
										
										
											2018-07-04 15:59:22 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-11 04:19:10 +08:00
										 |  |  | /** | 
					
						
							| 
									
										
										
										
											2018-12-12 17:46:44 +08:00
										 |  |  |  * @param {GetCacheGroups | Record<string, false|string|RegExp|OptimizationSplitChunksGetCacheGroups|OptimizationSplitChunksCacheGroup>} cacheGroups the cache group options | 
					
						
							| 
									
										
										
										
											2020-09-29 17:16:24 +08:00
										 |  |  |  * @param {string[]} defaultSizeTypes the default size types | 
					
						
							| 
									
										
										
										
											2018-12-11 04:19:10 +08:00
										 |  |  |  * @returns {GetCacheGroups} a function to get the cache groups | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2020-09-29 17:16:24 +08:00
										 |  |  | const normalizeCacheGroups = (cacheGroups, defaultSizeTypes) => { | 
					
						
							| 
									
										
										
										
											2018-12-11 04:19:10 +08:00
										 |  |  | 	if (typeof cacheGroups === "function") { | 
					
						
							|  |  |  | 		return cacheGroups; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if (typeof cacheGroups === "object" && cacheGroups !== null) { | 
					
						
							| 
									
										
										
										
											2020-06-16 22:40:07 +08:00
										 |  |  | 		/** @type {(function(Module, CacheGroupsContext, CacheGroupSource[]): void)[]} */ | 
					
						
							|  |  |  | 		const handlers = []; | 
					
						
							|  |  |  | 		for (const key of Object.keys(cacheGroups)) { | 
					
						
							|  |  |  | 			const option = cacheGroups[key]; | 
					
						
							|  |  |  | 			if (option === false) { | 
					
						
							|  |  |  | 				continue; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			if (typeof option === "string" || option instanceof RegExp) { | 
					
						
							| 
									
										
										
										
											2020-09-29 17:16:24 +08:00
										 |  |  | 				const source = createCacheGroupSource({}, key, defaultSizeTypes); | 
					
						
							| 
									
										
										
										
											2020-06-16 22:40:07 +08:00
										 |  |  | 				handlers.push((module, context, results) => { | 
					
						
							| 
									
										
										
										
											2018-12-11 04:19:10 +08:00
										 |  |  | 					if (checkTest(option, module, context)) { | 
					
						
							| 
									
										
										
										
											2020-06-16 22:40:07 +08:00
										 |  |  | 						results.push(source); | 
					
						
							| 
									
										
										
										
											2018-01-20 00:06:59 +08:00
										 |  |  | 					} | 
					
						
							| 
									
										
										
										
											2020-06-16 22:40:07 +08:00
										 |  |  | 				}); | 
					
						
							|  |  |  | 			} else if (typeof option === "function") { | 
					
						
							| 
									
										
										
										
											2020-09-29 17:16:24 +08:00
										 |  |  | 				const cache = new WeakMap(); | 
					
						
							| 
									
										
										
										
											2020-06-16 22:40:07 +08:00
										 |  |  | 				handlers.push((module, context, results) => { | 
					
						
							| 
									
										
										
										
											2018-12-12 17:46:44 +08:00
										 |  |  | 					const result = option(module); | 
					
						
							| 
									
										
										
										
											2018-12-11 04:19:10 +08:00
										 |  |  | 					if (result) { | 
					
						
							|  |  |  | 						const groups = Array.isArray(result) ? result : [result]; | 
					
						
							|  |  |  | 						for (const group of groups) { | 
					
						
							| 
									
										
										
										
											2020-09-29 17:16:24 +08:00
										 |  |  | 							const cachedSource = cache.get(group); | 
					
						
							|  |  |  | 							if (cachedSource !== undefined) { | 
					
						
							|  |  |  | 								results.push(cachedSource); | 
					
						
							|  |  |  | 							} else { | 
					
						
							|  |  |  | 								const source = createCacheGroupSource( | 
					
						
							|  |  |  | 									group, | 
					
						
							|  |  |  | 									key, | 
					
						
							|  |  |  | 									defaultSizeTypes | 
					
						
							|  |  |  | 								); | 
					
						
							|  |  |  | 								cache.set(group, source); | 
					
						
							|  |  |  | 								results.push(source); | 
					
						
							|  |  |  | 							} | 
					
						
							| 
									
										
										
										
											2018-01-20 00:06:59 +08:00
										 |  |  | 						} | 
					
						
							| 
									
										
										
										
											2018-12-11 04:19:10 +08:00
										 |  |  | 					} | 
					
						
							| 
									
										
										
										
											2020-06-16 22:40:07 +08:00
										 |  |  | 				}); | 
					
						
							|  |  |  | 			} else { | 
					
						
							| 
									
										
										
										
											2020-09-29 17:16:24 +08:00
										 |  |  | 				const source = createCacheGroupSource(option, key, defaultSizeTypes); | 
					
						
							| 
									
										
										
										
											2020-06-16 22:40:07 +08:00
										 |  |  | 				handlers.push((module, context, results) => { | 
					
						
							| 
									
										
										
										
											2018-12-11 04:19:10 +08:00
										 |  |  | 					if ( | 
					
						
							|  |  |  | 						checkTest(option.test, module, context) && | 
					
						
							| 
									
										
										
										
											2020-12-22 21:51:09 +08:00
										 |  |  | 						checkModuleType(option.type, module) && | 
					
						
							|  |  |  | 						checkModuleLayer(option.layer, module) | 
					
						
							| 
									
										
										
										
											2018-08-14 17:18:22 +08:00
										 |  |  | 					) { | 
					
						
							| 
									
										
										
										
											2020-06-16 22:40:07 +08:00
										 |  |  | 						results.push(source); | 
					
						
							| 
									
										
										
										
											2018-01-20 00:06:59 +08:00
										 |  |  | 					} | 
					
						
							| 
									
										
										
										
											2020-06-16 22:40:07 +08:00
										 |  |  | 				}); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		/** | 
					
						
							|  |  |  | 		 * @param {Module} module the current module | 
					
						
							|  |  |  | 		 * @param {CacheGroupsContext} context the current context | 
					
						
							|  |  |  | 		 * @returns {CacheGroupSource[]} the matching cache groups | 
					
						
							|  |  |  | 		 */ | 
					
						
							|  |  |  | 		const fn = (module, context) => { | 
					
						
							|  |  |  | 			/** @type {CacheGroupSource[]} */ | 
					
						
							|  |  |  | 			let results = []; | 
					
						
							|  |  |  | 			for (const fn of handlers) { | 
					
						
							|  |  |  | 				fn(module, context, results); | 
					
						
							| 
									
										
										
										
											2018-12-11 04:19:10 +08:00
										 |  |  | 			} | 
					
						
							|  |  |  | 			return results; | 
					
						
							|  |  |  | 		}; | 
					
						
							| 
									
										
										
										
											2018-01-20 00:06:59 +08:00
										 |  |  | 		return fn; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2018-12-11 04:19:10 +08:00
										 |  |  | 	return () => null; | 
					
						
							|  |  |  | }; | 
					
						
							| 
									
										
										
										
											2018-01-20 00:06:59 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-11 04:19:10 +08:00
										 |  |  | /** | 
					
						
							|  |  |  |  * @param {undefined|boolean|string|RegExp|Function} test test option | 
					
						
							|  |  |  |  * @param {Module} module the module | 
					
						
							|  |  |  |  * @param {CacheGroupsContext} context context object | 
					
						
							|  |  |  |  * @returns {boolean} true, if the module should be selected | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | const checkTest = (test, module, context) => { | 
					
						
							|  |  |  | 	if (test === undefined) return true; | 
					
						
							|  |  |  | 	if (typeof test === "function") { | 
					
						
							|  |  |  | 		return test(module, context); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if (typeof test === "boolean") return test; | 
					
						
							|  |  |  | 	if (typeof test === "string") { | 
					
						
							|  |  |  | 		const name = module.nameForCondition(); | 
					
						
							|  |  |  | 		return name && name.startsWith(test); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if (test instanceof RegExp) { | 
					
						
							|  |  |  | 		const name = module.nameForCondition(); | 
					
						
							|  |  |  | 		return name && test.test(name); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return false; | 
					
						
							|  |  |  | }; | 
					
						
							| 
									
										
										
										
											2018-08-14 17:18:22 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-11 04:19:10 +08:00
										 |  |  | /** | 
					
						
							|  |  |  |  * @param {undefined|string|RegExp|Function} test type option | 
					
						
							|  |  |  |  * @param {Module} module the module | 
					
						
							|  |  |  |  * @returns {boolean} true, if the module should be selected | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | const checkModuleType = (test, module) => { | 
					
						
							|  |  |  | 	if (test === undefined) return true; | 
					
						
							|  |  |  | 	if (typeof test === "function") { | 
					
						
							|  |  |  | 		return test(module.type); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if (typeof test === "string") { | 
					
						
							|  |  |  | 		const type = module.type; | 
					
						
							|  |  |  | 		return test === type; | 
					
						
							| 
									
										
										
										
											2018-01-20 00:06:59 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2018-12-11 04:19:10 +08:00
										 |  |  | 	if (test instanceof RegExp) { | 
					
						
							|  |  |  | 		const type = module.type; | 
					
						
							|  |  |  | 		return test.test(type); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return false; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-22 21:51:09 +08:00
										 |  |  | /** | 
					
						
							|  |  |  |  * @param {undefined|string|RegExp|Function} test type option | 
					
						
							|  |  |  |  * @param {Module} module the module | 
					
						
							|  |  |  |  * @returns {boolean} true, if the module should be selected | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | const checkModuleLayer = (test, module) => { | 
					
						
							|  |  |  | 	if (test === undefined) return true; | 
					
						
							|  |  |  | 	if (typeof test === "function") { | 
					
						
							|  |  |  | 		return test(module.layer); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if (typeof test === "string") { | 
					
						
							|  |  |  | 		const layer = module.layer; | 
					
						
							|  |  |  | 		return test === "" ? !layer : layer && layer.startsWith(test); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if (test instanceof RegExp) { | 
					
						
							|  |  |  | 		const layer = module.layer; | 
					
						
							|  |  |  | 		return test.test(layer); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return false; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-11 04:19:10 +08:00
										 |  |  | /** | 
					
						
							| 
									
										
										
										
											2020-06-16 22:40:07 +08:00
										 |  |  |  * @param {OptimizationSplitChunksCacheGroup} options the group options | 
					
						
							|  |  |  |  * @param {string} key key of cache group | 
					
						
							| 
									
										
										
										
											2020-09-29 17:16:24 +08:00
										 |  |  |  * @param {string[]} defaultSizeTypes the default size types | 
					
						
							| 
									
										
										
										
											2018-12-11 04:19:10 +08:00
										 |  |  |  * @returns {CacheGroupSource} the normalized cached group | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2020-09-29 17:16:24 +08:00
										 |  |  | const createCacheGroupSource = (options, key, defaultSizeTypes) => { | 
					
						
							|  |  |  | 	const minSize = normalizeSizes(options.minSize, defaultSizeTypes); | 
					
						
							| 
									
										
										
										
											2021-10-19 15:42:57 +08:00
										 |  |  | 	const minSizeReduction = normalizeSizes( | 
					
						
							|  |  |  | 		options.minSizeReduction, | 
					
						
							|  |  |  | 		defaultSizeTypes | 
					
						
							|  |  |  | 	); | 
					
						
							| 
									
										
										
										
											2020-09-29 17:16:24 +08:00
										 |  |  | 	const maxSize = normalizeSizes(options.maxSize, defaultSizeTypes); | 
					
						
							| 
									
										
										
										
											2018-12-11 04:19:10 +08:00
										 |  |  | 	return { | 
					
						
							| 
									
										
										
										
											2020-06-16 22:40:07 +08:00
										 |  |  | 		key, | 
					
						
							| 
									
										
										
										
											2018-12-11 04:19:10 +08:00
										 |  |  | 		priority: options.priority, | 
					
						
							| 
									
										
										
										
											2018-12-12 17:46:44 +08:00
										 |  |  | 		getName: normalizeName(options.name), | 
					
						
							| 
									
										
										
										
											2018-12-11 04:19:10 +08:00
										 |  |  | 		chunksFilter: normalizeChunksFilter(options.chunks), | 
					
						
							|  |  |  | 		enforce: options.enforce, | 
					
						
							| 
									
										
										
										
											2020-09-29 17:16:24 +08:00
										 |  |  | 		minSize, | 
					
						
							| 
									
										
										
										
											2021-10-19 15:42:57 +08:00
										 |  |  | 		minSizeReduction, | 
					
						
							| 
									
										
										
										
											2020-09-29 17:16:24 +08:00
										 |  |  | 		minRemainingSize: mergeSizes( | 
					
						
							|  |  |  | 			normalizeSizes(options.minRemainingSize, defaultSizeTypes), | 
					
						
							|  |  |  | 			minSize | 
					
						
							|  |  |  | 		), | 
					
						
							|  |  |  | 		enforceSizeThreshold: normalizeSizes( | 
					
						
							|  |  |  | 			options.enforceSizeThreshold, | 
					
						
							|  |  |  | 			defaultSizeTypes | 
					
						
							|  |  |  | 		), | 
					
						
							|  |  |  | 		maxAsyncSize: mergeSizes( | 
					
						
							|  |  |  | 			normalizeSizes(options.maxAsyncSize, defaultSizeTypes), | 
					
						
							|  |  |  | 			maxSize | 
					
						
							|  |  |  | 		), | 
					
						
							|  |  |  | 		maxInitialSize: mergeSizes( | 
					
						
							|  |  |  | 			normalizeSizes(options.maxInitialSize, defaultSizeTypes), | 
					
						
							|  |  |  | 			maxSize | 
					
						
							|  |  |  | 		), | 
					
						
							| 
									
										
										
										
											2018-12-11 04:19:10 +08:00
										 |  |  | 		minChunks: options.minChunks, | 
					
						
							|  |  |  | 		maxAsyncRequests: options.maxAsyncRequests, | 
					
						
							|  |  |  | 		maxInitialRequests: options.maxInitialRequests, | 
					
						
							|  |  |  | 		filename: options.filename, | 
					
						
							|  |  |  | 		idHint: options.idHint, | 
					
						
							|  |  |  | 		automaticNameDelimiter: options.automaticNameDelimiter, | 
					
						
							| 
									
										
										
										
											2020-07-28 00:09:48 +08:00
										 |  |  | 		reuseExistingChunk: options.reuseExistingChunk, | 
					
						
							|  |  |  | 		usedExports: options.usedExports | 
					
						
							| 
									
										
										
										
											2018-12-11 04:19:10 +08:00
										 |  |  | 	}; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | module.exports = class SplitChunksPlugin { | 
					
						
							| 
									
										
										
										
											2018-08-25 01:46:07 +08:00
										 |  |  | 	/** | 
					
						
							| 
									
										
										
										
											2018-12-11 04:19:10 +08:00
										 |  |  | 	 * @param {OptimizationSplitChunksOptions=} options plugin options | 
					
						
							| 
									
										
										
										
											2018-08-25 01:46:07 +08:00
										 |  |  | 	 */ | 
					
						
							| 
									
										
										
										
											2018-12-11 04:19:10 +08:00
										 |  |  | 	constructor(options = {}) { | 
					
						
							| 
									
										
										
										
											2020-09-29 17:16:24 +08:00
										 |  |  | 		const defaultSizeTypes = options.defaultSizeTypes || [ | 
					
						
							|  |  |  | 			"javascript", | 
					
						
							|  |  |  | 			"unknown" | 
					
						
							|  |  |  | 		]; | 
					
						
							| 
									
										
										
										
											2018-12-11 04:19:10 +08:00
										 |  |  | 		const fallbackCacheGroup = options.fallbackCacheGroup || {}; | 
					
						
							| 
									
										
										
										
											2020-09-29 17:16:24 +08:00
										 |  |  | 		const minSize = normalizeSizes(options.minSize, defaultSizeTypes); | 
					
						
							| 
									
										
										
										
											2021-10-19 15:42:57 +08:00
										 |  |  | 		const minSizeReduction = normalizeSizes( | 
					
						
							|  |  |  | 			options.minSizeReduction, | 
					
						
							|  |  |  | 			defaultSizeTypes | 
					
						
							|  |  |  | 		); | 
					
						
							| 
									
										
										
										
											2020-09-29 17:16:24 +08:00
										 |  |  | 		const maxSize = normalizeSizes(options.maxSize, defaultSizeTypes); | 
					
						
							| 
									
										
										
										
											2018-12-11 04:19:10 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		/** @type {SplitChunksOptions} */ | 
					
						
							|  |  |  | 		this.options = { | 
					
						
							|  |  |  | 			chunksFilter: normalizeChunksFilter(options.chunks || "all"), | 
					
						
							| 
									
										
										
										
											2020-09-29 17:16:24 +08:00
										 |  |  | 			defaultSizeTypes, | 
					
						
							|  |  |  | 			minSize, | 
					
						
							| 
									
										
										
										
											2021-10-19 15:42:57 +08:00
										 |  |  | 			minSizeReduction, | 
					
						
							| 
									
										
										
										
											2020-09-29 17:16:24 +08:00
										 |  |  | 			minRemainingSize: mergeSizes( | 
					
						
							|  |  |  | 				normalizeSizes(options.minRemainingSize, defaultSizeTypes), | 
					
						
							|  |  |  | 				minSize | 
					
						
							|  |  |  | 			), | 
					
						
							|  |  |  | 			enforceSizeThreshold: normalizeSizes( | 
					
						
							|  |  |  | 				options.enforceSizeThreshold, | 
					
						
							|  |  |  | 				defaultSizeTypes | 
					
						
							|  |  |  | 			), | 
					
						
							|  |  |  | 			maxAsyncSize: mergeSizes( | 
					
						
							|  |  |  | 				normalizeSizes(options.maxAsyncSize, defaultSizeTypes), | 
					
						
							|  |  |  | 				maxSize | 
					
						
							|  |  |  | 			), | 
					
						
							|  |  |  | 			maxInitialSize: mergeSizes( | 
					
						
							|  |  |  | 				normalizeSizes(options.maxInitialSize, defaultSizeTypes), | 
					
						
							|  |  |  | 				maxSize | 
					
						
							|  |  |  | 			), | 
					
						
							| 
									
										
										
										
											2018-12-11 04:19:10 +08:00
										 |  |  | 			minChunks: options.minChunks || 1, | 
					
						
							|  |  |  | 			maxAsyncRequests: options.maxAsyncRequests || 1, | 
					
						
							|  |  |  | 			maxInitialRequests: options.maxInitialRequests || 1, | 
					
						
							|  |  |  | 			hidePathInfo: options.hidePathInfo || false, | 
					
						
							|  |  |  | 			filename: options.filename || undefined, | 
					
						
							| 
									
										
										
										
											2020-09-29 17:16:24 +08:00
										 |  |  | 			getCacheGroups: normalizeCacheGroups( | 
					
						
							|  |  |  | 				options.cacheGroups, | 
					
						
							|  |  |  | 				defaultSizeTypes | 
					
						
							|  |  |  | 			), | 
					
						
							| 
									
										
										
										
											2018-12-12 17:46:44 +08:00
										 |  |  | 			getName: options.name ? normalizeName(options.name) : defaultGetName, | 
					
						
							| 
									
										
										
										
											2018-12-11 04:19:10 +08:00
										 |  |  | 			automaticNameDelimiter: options.automaticNameDelimiter, | 
					
						
							| 
									
										
										
										
											2020-07-28 00:09:48 +08:00
										 |  |  | 			usedExports: options.usedExports, | 
					
						
							| 
									
										
										
										
											2018-12-11 04:19:10 +08:00
										 |  |  | 			fallbackCacheGroup: { | 
					
						
							| 
									
										
										
										
											2021-11-02 20:23:09 +08:00
										 |  |  | 				chunksFilter: normalizeChunksFilter( | 
					
						
							|  |  |  | 					fallbackCacheGroup.chunks || options.chunks || "all" | 
					
						
							|  |  |  | 				), | 
					
						
							| 
									
										
										
										
											2020-09-29 17:16:24 +08:00
										 |  |  | 				minSize: mergeSizes( | 
					
						
							|  |  |  | 					normalizeSizes(fallbackCacheGroup.minSize, defaultSizeTypes), | 
					
						
							|  |  |  | 					minSize | 
					
						
							|  |  |  | 				), | 
					
						
							| 
									
										
										
										
											2018-12-12 03:47:50 +08:00
										 |  |  | 				maxAsyncSize: mergeSizes( | 
					
						
							| 
									
										
										
										
											2020-09-29 17:16:24 +08:00
										 |  |  | 					normalizeSizes(fallbackCacheGroup.maxAsyncSize, defaultSizeTypes), | 
					
						
							|  |  |  | 					normalizeSizes(fallbackCacheGroup.maxSize, defaultSizeTypes), | 
					
						
							|  |  |  | 					normalizeSizes(options.maxAsyncSize, defaultSizeTypes), | 
					
						
							|  |  |  | 					normalizeSizes(options.maxSize, defaultSizeTypes) | 
					
						
							| 
									
										
										
										
											2018-12-12 03:47:50 +08:00
										 |  |  | 				), | 
					
						
							|  |  |  | 				maxInitialSize: mergeSizes( | 
					
						
							| 
									
										
										
										
											2020-09-29 17:16:24 +08:00
										 |  |  | 					normalizeSizes(fallbackCacheGroup.maxInitialSize, defaultSizeTypes), | 
					
						
							|  |  |  | 					normalizeSizes(fallbackCacheGroup.maxSize, defaultSizeTypes), | 
					
						
							|  |  |  | 					normalizeSizes(options.maxInitialSize, defaultSizeTypes), | 
					
						
							|  |  |  | 					normalizeSizes(options.maxSize, defaultSizeTypes) | 
					
						
							| 
									
										
										
										
											2018-12-12 03:47:50 +08:00
										 |  |  | 				), | 
					
						
							| 
									
										
										
										
											2018-12-11 04:19:10 +08:00
										 |  |  | 				automaticNameDelimiter: | 
					
						
							|  |  |  | 					fallbackCacheGroup.automaticNameDelimiter || | 
					
						
							|  |  |  | 					options.automaticNameDelimiter || | 
					
						
							|  |  |  | 					"~" | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		}; | 
					
						
							| 
									
										
										
										
											2020-06-16 22:40:07 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		/** @type {WeakMap<CacheGroupSource, CacheGroup>} */ | 
					
						
							|  |  |  | 		this._cacheGroupCache = new WeakMap(); | 
					
						
							| 
									
										
										
										
											2018-08-25 01:46:07 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2018-01-20 00:06:59 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-28 00:09:48 +08:00
										 |  |  | 	/** | 
					
						
							|  |  |  | 	 * @param {CacheGroupSource} cacheGroupSource source | 
					
						
							|  |  |  | 	 * @returns {CacheGroup} the cache group (cached) | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 	_getCacheGroup(cacheGroupSource) { | 
					
						
							|  |  |  | 		const cacheEntry = this._cacheGroupCache.get(cacheGroupSource); | 
					
						
							|  |  |  | 		if (cacheEntry !== undefined) return cacheEntry; | 
					
						
							|  |  |  | 		const minSize = mergeSizes( | 
					
						
							|  |  |  | 			cacheGroupSource.minSize, | 
					
						
							|  |  |  | 			cacheGroupSource.enforce ? undefined : this.options.minSize | 
					
						
							|  |  |  | 		); | 
					
						
							| 
									
										
										
										
											2021-10-19 15:42:57 +08:00
										 |  |  | 		const minSizeReduction = mergeSizes( | 
					
						
							|  |  |  | 			cacheGroupSource.minSizeReduction, | 
					
						
							|  |  |  | 			cacheGroupSource.enforce ? undefined : this.options.minSizeReduction | 
					
						
							|  |  |  | 		); | 
					
						
							| 
									
										
										
										
											2020-07-28 00:09:48 +08:00
										 |  |  | 		const minRemainingSize = mergeSizes( | 
					
						
							|  |  |  | 			cacheGroupSource.minRemainingSize, | 
					
						
							|  |  |  | 			cacheGroupSource.enforce ? undefined : this.options.minRemainingSize | 
					
						
							|  |  |  | 		); | 
					
						
							|  |  |  | 		const enforceSizeThreshold = mergeSizes( | 
					
						
							|  |  |  | 			cacheGroupSource.enforceSizeThreshold, | 
					
						
							|  |  |  | 			cacheGroupSource.enforce ? undefined : this.options.enforceSizeThreshold | 
					
						
							|  |  |  | 		); | 
					
						
							|  |  |  | 		const cacheGroup = { | 
					
						
							|  |  |  | 			key: cacheGroupSource.key, | 
					
						
							|  |  |  | 			priority: cacheGroupSource.priority || 0, | 
					
						
							|  |  |  | 			chunksFilter: cacheGroupSource.chunksFilter || this.options.chunksFilter, | 
					
						
							|  |  |  | 			minSize, | 
					
						
							| 
									
										
										
										
											2021-10-19 15:42:57 +08:00
										 |  |  | 			minSizeReduction, | 
					
						
							| 
									
										
										
										
											2020-07-28 00:09:48 +08:00
										 |  |  | 			minRemainingSize, | 
					
						
							|  |  |  | 			enforceSizeThreshold, | 
					
						
							|  |  |  | 			maxAsyncSize: mergeSizes( | 
					
						
							|  |  |  | 				cacheGroupSource.maxAsyncSize, | 
					
						
							|  |  |  | 				cacheGroupSource.enforce ? undefined : this.options.maxAsyncSize | 
					
						
							|  |  |  | 			), | 
					
						
							|  |  |  | 			maxInitialSize: mergeSizes( | 
					
						
							|  |  |  | 				cacheGroupSource.maxInitialSize, | 
					
						
							|  |  |  | 				cacheGroupSource.enforce ? undefined : this.options.maxInitialSize | 
					
						
							|  |  |  | 			), | 
					
						
							|  |  |  | 			minChunks: | 
					
						
							|  |  |  | 				cacheGroupSource.minChunks !== undefined | 
					
						
							|  |  |  | 					? cacheGroupSource.minChunks | 
					
						
							|  |  |  | 					: cacheGroupSource.enforce | 
					
						
							|  |  |  | 					? 1 | 
					
						
							|  |  |  | 					: this.options.minChunks, | 
					
						
							|  |  |  | 			maxAsyncRequests: | 
					
						
							|  |  |  | 				cacheGroupSource.maxAsyncRequests !== undefined | 
					
						
							|  |  |  | 					? cacheGroupSource.maxAsyncRequests | 
					
						
							|  |  |  | 					: cacheGroupSource.enforce | 
					
						
							|  |  |  | 					? Infinity | 
					
						
							|  |  |  | 					: this.options.maxAsyncRequests, | 
					
						
							|  |  |  | 			maxInitialRequests: | 
					
						
							|  |  |  | 				cacheGroupSource.maxInitialRequests !== undefined | 
					
						
							|  |  |  | 					? cacheGroupSource.maxInitialRequests | 
					
						
							|  |  |  | 					: cacheGroupSource.enforce | 
					
						
							|  |  |  | 					? Infinity | 
					
						
							|  |  |  | 					: this.options.maxInitialRequests, | 
					
						
							|  |  |  | 			getName: | 
					
						
							|  |  |  | 				cacheGroupSource.getName !== undefined | 
					
						
							|  |  |  | 					? cacheGroupSource.getName | 
					
						
							|  |  |  | 					: this.options.getName, | 
					
						
							|  |  |  | 			usedExports: | 
					
						
							|  |  |  | 				cacheGroupSource.usedExports !== undefined | 
					
						
							|  |  |  | 					? cacheGroupSource.usedExports | 
					
						
							|  |  |  | 					: this.options.usedExports, | 
					
						
							|  |  |  | 			filename: | 
					
						
							|  |  |  | 				cacheGroupSource.filename !== undefined | 
					
						
							|  |  |  | 					? cacheGroupSource.filename | 
					
						
							|  |  |  | 					: this.options.filename, | 
					
						
							|  |  |  | 			automaticNameDelimiter: | 
					
						
							|  |  |  | 				cacheGroupSource.automaticNameDelimiter !== undefined | 
					
						
							|  |  |  | 					? cacheGroupSource.automaticNameDelimiter | 
					
						
							|  |  |  | 					: this.options.automaticNameDelimiter, | 
					
						
							|  |  |  | 			idHint: | 
					
						
							|  |  |  | 				cacheGroupSource.idHint !== undefined | 
					
						
							|  |  |  | 					? cacheGroupSource.idHint | 
					
						
							|  |  |  | 					: cacheGroupSource.key, | 
					
						
							|  |  |  | 			reuseExistingChunk: cacheGroupSource.reuseExistingChunk || false, | 
					
						
							|  |  |  | 			_validateSize: hasNonZeroSizes(minSize), | 
					
						
							|  |  |  | 			_validateRemainingSize: hasNonZeroSizes(minRemainingSize), | 
					
						
							|  |  |  | 			_minSizeForMaxSize: mergeSizes( | 
					
						
							|  |  |  | 				cacheGroupSource.minSize, | 
					
						
							|  |  |  | 				this.options.minSize | 
					
						
							|  |  |  | 			), | 
					
						
							|  |  |  | 			_conditionalEnforce: hasNonZeroSizes(enforceSizeThreshold) | 
					
						
							|  |  |  | 		}; | 
					
						
							|  |  |  | 		this._cacheGroupCache.set(cacheGroupSource, cacheGroup); | 
					
						
							|  |  |  | 		return cacheGroup; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-04 15:59:22 +08:00
										 |  |  | 	/** | 
					
						
							| 
									
										
										
										
											2020-04-23 16:48:36 +08:00
										 |  |  | 	 * Apply the plugin | 
					
						
							|  |  |  | 	 * @param {Compiler} compiler the compiler instance | 
					
						
							| 
									
										
										
										
											2018-07-04 15:59:22 +08:00
										 |  |  | 	 * @returns {void} | 
					
						
							|  |  |  | 	 */ | 
					
						
							| 
									
										
										
										
											2018-01-20 00:06:59 +08:00
										 |  |  | 	apply(compiler) { | 
					
						
							| 
									
										
										
										
											2021-08-06 17:50:55 +08:00
										 |  |  | 		const cachedMakePathsRelative = makePathsRelative.bindContextCache( | 
					
						
							| 
									
										
										
										
											2020-01-15 06:14:47 +08:00
										 |  |  | 			compiler.context, | 
					
						
							|  |  |  | 			compiler.root | 
					
						
							|  |  |  | 		); | 
					
						
							| 
									
										
										
										
											2018-01-24 19:00:50 +08:00
										 |  |  | 		compiler.hooks.thisCompilation.tap("SplitChunksPlugin", compilation => { | 
					
						
							| 
									
										
										
										
											2019-07-25 21:46:08 +08:00
										 |  |  | 			const logger = compilation.getLogger("webpack.SplitChunksPlugin"); | 
					
						
							| 
									
										
										
										
											2018-01-20 20:11:02 +08:00
										 |  |  | 			let alreadyOptimized = false; | 
					
						
							| 
									
										
										
										
											2018-01-20 00:06:59 +08:00
										 |  |  | 			compilation.hooks.unseal.tap("SplitChunksPlugin", () => { | 
					
						
							| 
									
										
										
										
											2018-01-20 20:11:02 +08:00
										 |  |  | 				alreadyOptimized = false; | 
					
						
							| 
									
										
										
										
											2018-01-20 00:06:59 +08:00
										 |  |  | 			}); | 
					
						
							| 
									
										
										
										
											2018-07-31 04:30:27 +08:00
										 |  |  | 			compilation.hooks.optimizeChunks.tap( | 
					
						
							| 
									
										
										
										
											2018-12-09 19:54:17 +08:00
										 |  |  | 				{ | 
					
						
							| 
									
										
										
										
											2018-07-31 04:30:27 +08:00
										 |  |  | 					name: "SplitChunksPlugin", | 
					
						
							|  |  |  | 					stage: STAGE_ADVANCED | 
					
						
							| 
									
										
										
										
											2018-12-09 19:54:17 +08:00
										 |  |  | 				}, | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 				chunks => { | 
					
						
							|  |  |  | 					if (alreadyOptimized) return; | 
					
						
							|  |  |  | 					alreadyOptimized = true; | 
					
						
							| 
									
										
										
										
											2019-07-25 21:46:08 +08:00
										 |  |  | 					logger.time("prepare"); | 
					
						
							| 
									
										
										
										
											2018-08-14 17:18:22 +08:00
										 |  |  | 					const chunkGraph = compilation.chunkGraph; | 
					
						
							|  |  |  | 					const moduleGraph = compilation.moduleGraph; | 
					
						
							| 
									
										
										
										
											2021-10-08 21:08:48 +08:00
										 |  |  | 					// Give each selected chunk an index (to create strings from chunks)
 | 
					
						
							|  |  |  | 					/** @type {Map<Chunk, bigint>} */ | 
					
						
							|  |  |  | 					const chunkIndexMap = new Map(); | 
					
						
							|  |  |  | 					const ZERO = BigInt("0"); | 
					
						
							|  |  |  | 					const ONE = BigInt("1"); | 
					
						
							| 
									
										
										
										
											2021-10-12 15:49:48 +08:00
										 |  |  | 					const START = ONE << BigInt("31"); | 
					
						
							|  |  |  | 					let index = START; | 
					
						
							| 
									
										
										
										
											2021-10-08 21:08:48 +08:00
										 |  |  | 					for (const chunk of chunks) { | 
					
						
							| 
									
										
										
										
											2021-10-12 15:49:48 +08:00
										 |  |  | 						chunkIndexMap.set( | 
					
						
							|  |  |  | 							chunk, | 
					
						
							|  |  |  | 							index | BigInt((Math.random() * 0x7fffffff) | 0) | 
					
						
							|  |  |  | 						); | 
					
						
							| 
									
										
										
										
											2021-10-08 21:08:48 +08:00
										 |  |  | 						index = index << ONE; | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 					/** | 
					
						
							|  |  |  | 					 * @param {Iterable<Chunk>} chunks list of chunks | 
					
						
							|  |  |  | 					 * @returns {bigint | Chunk} key of the chunks | 
					
						
							|  |  |  | 					 */ | 
					
						
							|  |  |  | 					const getKey = chunks => { | 
					
						
							|  |  |  | 						const iterator = chunks[Symbol.iterator](); | 
					
						
							|  |  |  | 						let result = iterator.next(); | 
					
						
							|  |  |  | 						if (result.done) return ZERO; | 
					
						
							|  |  |  | 						const first = result.value; | 
					
						
							|  |  |  | 						result = iterator.next(); | 
					
						
							|  |  |  | 						if (result.done) return first; | 
					
						
							|  |  |  | 						let key = | 
					
						
							|  |  |  | 							chunkIndexMap.get(first) | chunkIndexMap.get(result.value); | 
					
						
							|  |  |  | 						while (!(result = iterator.next()).done) { | 
					
						
							| 
									
										
										
										
											2021-10-12 15:49:48 +08:00
										 |  |  | 							const raw = chunkIndexMap.get(result.value); | 
					
						
							|  |  |  | 							key = key ^ raw; | 
					
						
							| 
									
										
										
										
											2021-10-08 21:08:48 +08:00
										 |  |  | 						} | 
					
						
							|  |  |  | 						return key; | 
					
						
							|  |  |  | 					}; | 
					
						
							|  |  |  | 					const keyToString = key => { | 
					
						
							|  |  |  | 						if (typeof key === "bigint") return key.toString(16); | 
					
						
							|  |  |  | 						return chunkIndexMap.get(key).toString(16); | 
					
						
							|  |  |  | 					}; | 
					
						
							| 
									
										
										
										
											2020-07-28 00:09:48 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-08 21:08:48 +08:00
										 |  |  | 					const getChunkSetsInGraph = memoize(() => { | 
					
						
							|  |  |  | 						/** @type {Map<bigint, Set<Chunk>>} */ | 
					
						
							|  |  |  | 						const chunkSetsInGraph = new Map(); | 
					
						
							|  |  |  | 						/** @type {Set<Chunk>} */ | 
					
						
							|  |  |  | 						const singleChunkSets = new Set(); | 
					
						
							| 
									
										
										
										
											2020-07-28 00:09:48 +08:00
										 |  |  | 						for (const module of compilation.modules) { | 
					
						
							| 
									
										
										
										
											2021-10-08 21:08:48 +08:00
										 |  |  | 							const chunks = chunkGraph.getModuleChunksIterable(module); | 
					
						
							|  |  |  | 							const chunksKey = getKey(chunks); | 
					
						
							|  |  |  | 							if (typeof chunksKey === "bigint") { | 
					
						
							|  |  |  | 								if (!chunkSetsInGraph.has(chunksKey)) { | 
					
						
							|  |  |  | 									chunkSetsInGraph.set(chunksKey, new Set(chunks)); | 
					
						
							|  |  |  | 								} | 
					
						
							|  |  |  | 							} else { | 
					
						
							|  |  |  | 								singleChunkSets.add(chunksKey); | 
					
						
							|  |  |  | 							} | 
					
						
							| 
									
										
										
										
											2018-04-27 20:29:34 +08:00
										 |  |  | 						} | 
					
						
							| 
									
										
										
										
											2021-10-08 21:08:48 +08:00
										 |  |  | 						return { chunkSetsInGraph, singleChunkSets }; | 
					
						
							| 
									
										
										
										
											2020-07-28 00:09:48 +08:00
										 |  |  | 					}); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					/** | 
					
						
							|  |  |  | 					 * @param {Module} module the module | 
					
						
							| 
									
										
										
										
											2021-10-08 21:08:48 +08:00
										 |  |  | 					 * @returns {Iterable<Chunk[]>} groups of chunks with equal exports | 
					
						
							| 
									
										
										
										
											2020-07-28 00:09:48 +08:00
										 |  |  | 					 */ | 
					
						
							|  |  |  | 					const groupChunksByExports = module => { | 
					
						
							|  |  |  | 						const exportsInfo = moduleGraph.getExportsInfo(module); | 
					
						
							|  |  |  | 						const groupedByUsedExports = new Map(); | 
					
						
							|  |  |  | 						for (const chunk of chunkGraph.getModuleChunksIterable(module)) { | 
					
						
							|  |  |  | 							const key = exportsInfo.getUsageKey(chunk.runtime); | 
					
						
							| 
									
										
										
										
											2021-10-08 21:08:48 +08:00
										 |  |  | 							const list = groupedByUsedExports.get(key); | 
					
						
							|  |  |  | 							if (list !== undefined) { | 
					
						
							|  |  |  | 								list.push(chunk); | 
					
						
							|  |  |  | 							} else { | 
					
						
							|  |  |  | 								groupedByUsedExports.set(key, [chunk]); | 
					
						
							|  |  |  | 							} | 
					
						
							| 
									
										
										
										
											2020-07-28 00:09:48 +08:00
										 |  |  | 						} | 
					
						
							|  |  |  | 						return groupedByUsedExports.values(); | 
					
						
							|  |  |  | 					}; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-08 21:08:48 +08:00
										 |  |  | 					/** @type {Map<Module, Iterable<Chunk[]>>} */ | 
					
						
							| 
									
										
										
										
											2020-07-28 00:09:48 +08:00
										 |  |  | 					const groupedByExportsMap = new Map(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-08 21:08:48 +08:00
										 |  |  | 					const getExportsChunkSetsInGraph = memoize(() => { | 
					
						
							|  |  |  | 						/** @type {Map<bigint, Set<Chunk>>} */ | 
					
						
							|  |  |  | 						const chunkSetsInGraph = new Map(); | 
					
						
							|  |  |  | 						/** @type {Set<Chunk>} */ | 
					
						
							|  |  |  | 						const singleChunkSets = new Set(); | 
					
						
							| 
									
										
										
										
											2020-07-28 00:09:48 +08:00
										 |  |  | 						for (const module of compilation.modules) { | 
					
						
							|  |  |  | 							const groupedChunks = Array.from(groupChunksByExports(module)); | 
					
						
							|  |  |  | 							groupedByExportsMap.set(module, groupedChunks); | 
					
						
							| 
									
										
										
										
											2021-10-08 21:08:48 +08:00
										 |  |  | 							for (const chunks of groupedChunks) { | 
					
						
							|  |  |  | 								if (chunks.length === 1) { | 
					
						
							|  |  |  | 									singleChunkSets.add(chunks[0]); | 
					
						
							|  |  |  | 								} else { | 
					
						
							|  |  |  | 									const chunksKey = /** @type {bigint} */ (getKey(chunks)); | 
					
						
							|  |  |  | 									if (!chunkSetsInGraph.has(chunksKey)) { | 
					
						
							|  |  |  | 										chunkSetsInGraph.set(chunksKey, new Set(chunks)); | 
					
						
							|  |  |  | 									} | 
					
						
							|  |  |  | 								} | 
					
						
							| 
									
										
										
										
											2020-07-28 00:09:48 +08:00
										 |  |  | 							} | 
					
						
							|  |  |  | 						} | 
					
						
							| 
									
										
										
										
											2021-10-08 21:08:48 +08:00
										 |  |  | 						return { chunkSetsInGraph, singleChunkSets }; | 
					
						
							| 
									
										
										
										
											2020-07-28 00:09:48 +08:00
										 |  |  | 					}); | 
					
						
							| 
									
										
										
										
											2018-04-27 20:29:34 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 					// group these set of chunks by count
 | 
					
						
							|  |  |  | 					// to allow to check less sets via isSubset
 | 
					
						
							|  |  |  | 					// (only smaller sets can be subset)
 | 
					
						
							| 
									
										
										
										
											2021-10-08 21:08:48 +08:00
										 |  |  | 					const groupChunkSetsByCount = chunkSets => { | 
					
						
							|  |  |  | 						/** @type {Map<number, Array<Set<Chunk>>>} */ | 
					
						
							|  |  |  | 						const chunkSetsByCount = new Map(); | 
					
						
							|  |  |  | 						for (const chunksSet of chunkSets) { | 
					
						
							| 
									
										
										
										
											2020-07-28 00:09:48 +08:00
										 |  |  | 							const count = chunksSet.size; | 
					
						
							| 
									
										
										
										
											2021-10-08 21:08:48 +08:00
										 |  |  | 							let array = chunkSetsByCount.get(count); | 
					
						
							| 
									
										
										
										
											2020-07-28 00:09:48 +08:00
										 |  |  | 							if (array === undefined) { | 
					
						
							|  |  |  | 								array = []; | 
					
						
							| 
									
										
										
										
											2021-10-08 21:08:48 +08:00
										 |  |  | 								chunkSetsByCount.set(count, array); | 
					
						
							| 
									
										
										
										
											2020-07-28 00:09:48 +08:00
										 |  |  | 							} | 
					
						
							|  |  |  | 							array.push(chunksSet); | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 						} | 
					
						
							| 
									
										
										
										
											2021-10-08 21:08:48 +08:00
										 |  |  | 						return chunkSetsByCount; | 
					
						
							| 
									
										
										
										
											2020-07-28 00:09:48 +08:00
										 |  |  | 					}; | 
					
						
							| 
									
										
										
										
											2021-10-08 21:08:48 +08:00
										 |  |  | 					const getChunkSetsByCount = memoize(() => | 
					
						
							|  |  |  | 						groupChunkSetsByCount( | 
					
						
							|  |  |  | 							getChunkSetsInGraph().chunkSetsInGraph.values() | 
					
						
							|  |  |  | 						) | 
					
						
							| 
									
										
										
										
											2020-07-28 00:09:48 +08:00
										 |  |  | 					); | 
					
						
							| 
									
										
										
										
											2021-10-08 21:08:48 +08:00
										 |  |  | 					const getExportsChunkSetsByCount = memoize(() => | 
					
						
							|  |  |  | 						groupChunkSetsByCount( | 
					
						
							|  |  |  | 							getExportsChunkSetsInGraph().chunkSetsInGraph.values() | 
					
						
							|  |  |  | 						) | 
					
						
							| 
									
										
										
										
											2020-07-28 00:09:48 +08:00
										 |  |  | 					); | 
					
						
							| 
									
										
										
										
											2018-04-27 20:29:34 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-08 21:08:48 +08:00
										 |  |  | 					// Create a list of possible combinations
 | 
					
						
							|  |  |  | 					const createGetCombinations = ( | 
					
						
							|  |  |  | 						chunkSets, | 
					
						
							|  |  |  | 						singleChunkSets, | 
					
						
							|  |  |  | 						chunkSetsByCount | 
					
						
							|  |  |  | 					) => { | 
					
						
							|  |  |  | 						/** @type {Map<bigint | Chunk, (Set<Chunk> | Chunk)[]>} */ | 
					
						
							| 
									
										
										
										
											2020-07-28 00:09:48 +08:00
										 |  |  | 						const combinationsCache = new Map(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-08 21:08:48 +08:00
										 |  |  | 						return key => { | 
					
						
							|  |  |  | 							const cacheEntry = combinationsCache.get(key); | 
					
						
							| 
									
										
										
										
											2020-07-28 00:09:48 +08:00
										 |  |  | 							if (cacheEntry !== undefined) return cacheEntry; | 
					
						
							| 
									
										
										
										
											2021-10-08 21:08:48 +08:00
										 |  |  | 							if (key instanceof Chunk) { | 
					
						
							|  |  |  | 								const result = [key]; | 
					
						
							|  |  |  | 								combinationsCache.set(key, result); | 
					
						
							| 
									
										
										
										
											2020-08-13 22:54:24 +08:00
										 |  |  | 								return result; | 
					
						
							|  |  |  | 							} | 
					
						
							| 
									
										
										
										
											2021-10-08 21:08:48 +08:00
										 |  |  | 							const chunksSet = chunkSets.get(key); | 
					
						
							|  |  |  | 							/** @type {(Set<Chunk> | Chunk)[]} */ | 
					
						
							|  |  |  | 							const array = [chunksSet]; | 
					
						
							|  |  |  | 							for (const [count, setArray] of chunkSetsByCount) { | 
					
						
							| 
									
										
										
										
											2020-08-13 22:54:24 +08:00
										 |  |  | 								// "equal" is not needed because they would have been merge in the first step
 | 
					
						
							| 
									
										
										
										
											2021-10-08 21:08:48 +08:00
										 |  |  | 								if (count < chunksSet.size) { | 
					
						
							| 
									
										
										
										
											2020-08-13 22:54:24 +08:00
										 |  |  | 									for (const set of setArray) { | 
					
						
							| 
									
										
										
										
											2021-10-08 21:08:48 +08:00
										 |  |  | 										if (isSubset(chunksSet, set)) { | 
					
						
							| 
									
										
										
										
											2020-08-13 22:54:24 +08:00
										 |  |  | 											array.push(set); | 
					
						
							| 
									
										
										
										
											2018-04-27 20:29:34 +08:00
										 |  |  | 										} | 
					
						
							|  |  |  | 									} | 
					
						
							|  |  |  | 								} | 
					
						
							|  |  |  | 							} | 
					
						
							| 
									
										
										
										
											2021-10-08 21:08:48 +08:00
										 |  |  | 							for (const chunk of singleChunkSets) { | 
					
						
							|  |  |  | 								if (chunksSet.has(chunk)) { | 
					
						
							|  |  |  | 									array.push(chunk); | 
					
						
							|  |  |  | 								} | 
					
						
							|  |  |  | 							} | 
					
						
							|  |  |  | 							combinationsCache.set(key, array); | 
					
						
							| 
									
										
										
										
											2020-07-28 00:09:48 +08:00
										 |  |  | 							return array; | 
					
						
							|  |  |  | 						}; | 
					
						
							| 
									
										
										
										
											2018-04-27 20:29:34 +08:00
										 |  |  | 					}; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-27 05:32:57 +08:00
										 |  |  | 					const getCombinationsFactory = memoize(() => { | 
					
						
							| 
									
										
										
										
											2021-10-08 21:08:48 +08:00
										 |  |  | 						const { chunkSetsInGraph, singleChunkSets } = getChunkSetsInGraph(); | 
					
						
							|  |  |  | 						return createGetCombinations( | 
					
						
							|  |  |  | 							chunkSetsInGraph, | 
					
						
							|  |  |  | 							singleChunkSets, | 
					
						
							|  |  |  | 							getChunkSetsByCount() | 
					
						
							|  |  |  | 						); | 
					
						
							| 
									
										
										
										
											2020-08-13 22:54:24 +08:00
										 |  |  | 					}); | 
					
						
							| 
									
										
										
										
											2020-07-28 00:09:48 +08:00
										 |  |  | 					const getCombinations = key => getCombinationsFactory()(key); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-27 05:32:57 +08:00
										 |  |  | 					const getExportsCombinationsFactory = memoize(() => { | 
					
						
							| 
									
										
										
										
											2021-10-08 21:08:48 +08:00
										 |  |  | 						const { chunkSetsInGraph, singleChunkSets } = | 
					
						
							|  |  |  | 							getExportsChunkSetsInGraph(); | 
					
						
							|  |  |  | 						return createGetCombinations( | 
					
						
							|  |  |  | 							chunkSetsInGraph, | 
					
						
							|  |  |  | 							singleChunkSets, | 
					
						
							|  |  |  | 							getExportsChunkSetsByCount() | 
					
						
							|  |  |  | 						); | 
					
						
							| 
									
										
										
										
											2020-08-13 22:54:24 +08:00
										 |  |  | 					}); | 
					
						
							| 
									
										
										
										
											2020-07-28 00:09:48 +08:00
										 |  |  | 					const getExportsCombinations = key => | 
					
						
							|  |  |  | 						getExportsCombinationsFactory()(key); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-08 21:08:48 +08:00
										 |  |  | 					/** | 
					
						
							|  |  |  | 					 * @typedef {Object} SelectedChunksResult | 
					
						
							|  |  |  | 					 * @property {Chunk[]} chunks the list of chunks | 
					
						
							|  |  |  | 					 * @property {bigint | Chunk} key a key of the list | 
					
						
							|  |  |  | 					 */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					/** @type {WeakMap<Set<Chunk> | Chunk, WeakMap<ChunkFilterFunction, SelectedChunksResult>>} */ | 
					
						
							| 
									
										
										
										
											2018-05-17 18:35:13 +08:00
										 |  |  | 					const selectedChunksCacheByChunksSet = new WeakMap(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					/** | 
					
						
							| 
									
										
										
										
											2021-10-08 21:08:48 +08:00
										 |  |  | 					 * get list and key by applying the filter function to the list | 
					
						
							| 
									
										
										
										
											2018-05-17 18:35:13 +08:00
										 |  |  | 					 * It is cached for performance reasons | 
					
						
							| 
									
										
										
										
											2021-10-08 21:08:48 +08:00
										 |  |  | 					 * @param {Set<Chunk> | Chunk} chunks list of chunks | 
					
						
							| 
									
										
										
										
											2018-05-17 18:35:13 +08:00
										 |  |  | 					 * @param {ChunkFilterFunction} chunkFilter filter function for chunks | 
					
						
							| 
									
										
										
										
											2021-10-08 21:08:48 +08:00
										 |  |  | 					 * @returns {SelectedChunksResult} list and key | 
					
						
							| 
									
										
										
										
											2018-05-17 18:35:13 +08:00
										 |  |  | 					 */ | 
					
						
							| 
									
										
										
										
											2018-04-27 20:29:34 +08:00
										 |  |  | 					const getSelectedChunks = (chunks, chunkFilter) => { | 
					
						
							|  |  |  | 						let entry = selectedChunksCacheByChunksSet.get(chunks); | 
					
						
							|  |  |  | 						if (entry === undefined) { | 
					
						
							| 
									
										
										
										
											2018-05-17 18:35:13 +08:00
										 |  |  | 							entry = new WeakMap(); | 
					
						
							| 
									
										
										
										
											2018-04-27 20:29:34 +08:00
										 |  |  | 							selectedChunksCacheByChunksSet.set(chunks, entry); | 
					
						
							|  |  |  | 						} | 
					
						
							| 
									
										
										
										
											2021-10-08 21:08:48 +08:00
										 |  |  | 						/** @type {SelectedChunksResult} */ | 
					
						
							| 
									
										
										
										
											2018-04-27 20:29:34 +08:00
										 |  |  | 						let entry2 = entry.get(chunkFilter); | 
					
						
							|  |  |  | 						if (entry2 === undefined) { | 
					
						
							| 
									
										
										
										
											2021-10-08 21:08:48 +08:00
										 |  |  | 							/** @type {Chunk[]} */ | 
					
						
							|  |  |  | 							const selectedChunks = []; | 
					
						
							|  |  |  | 							if (chunks instanceof Chunk) { | 
					
						
							|  |  |  | 								if (chunkFilter(chunks)) selectedChunks.push(chunks); | 
					
						
							|  |  |  | 							} else { | 
					
						
							|  |  |  | 								for (const chunk of chunks) { | 
					
						
							|  |  |  | 									if (chunkFilter(chunk)) selectedChunks.push(chunk); | 
					
						
							|  |  |  | 								} | 
					
						
							| 
									
										
										
										
											2018-04-27 20:29:34 +08:00
										 |  |  | 							} | 
					
						
							| 
									
										
										
										
											2021-10-08 21:08:48 +08:00
										 |  |  | 							entry2 = { | 
					
						
							|  |  |  | 								chunks: selectedChunks, | 
					
						
							|  |  |  | 								key: getKey(selectedChunks) | 
					
						
							|  |  |  | 							}; | 
					
						
							| 
									
										
										
										
											2018-04-27 20:29:34 +08:00
										 |  |  | 							entry.set(chunkFilter, entry2); | 
					
						
							|  |  |  | 						} | 
					
						
							|  |  |  | 						return entry2; | 
					
						
							|  |  |  | 					}; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-25 15:51:30 +08:00
										 |  |  | 					/** @type {Map<string, boolean>} */ | 
					
						
							|  |  |  | 					const alreadyValidatedParents = new Map(); | 
					
						
							| 
									
										
										
										
											2018-08-25 03:06:52 +08:00
										 |  |  | 					/** @type {Set<string>} */ | 
					
						
							| 
									
										
										
										
											2020-09-25 15:51:30 +08:00
										 |  |  | 					const alreadyReportedErrors = new Set(); | 
					
						
							| 
									
										
										
										
											2018-08-25 03:06:52 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 					// Map a list of chunks to a list of modules
 | 
					
						
							|  |  |  | 					// For the key the chunk "index" is used, the value is a SortableSet of modules
 | 
					
						
							| 
									
										
										
										
											2018-05-17 18:35:13 +08:00
										 |  |  | 					/** @type {Map<string, ChunksInfoItem>} */ | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 					const chunksInfoMap = new Map(); | 
					
						
							| 
									
										
										
										
											2018-04-27 20:29:34 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-17 18:35:13 +08:00
										 |  |  | 					/** | 
					
						
							| 
									
										
										
										
											2018-12-11 04:19:10 +08:00
										 |  |  | 					 * @param {CacheGroup} cacheGroup the current cache group | 
					
						
							| 
									
										
										
										
											2020-07-13 16:12:17 +08:00
										 |  |  | 					 * @param {number} cacheGroupIndex the index of the cache group of ordering | 
					
						
							| 
									
										
										
										
											2021-10-08 21:08:48 +08:00
										 |  |  | 					 * @param {Chunk[]} selectedChunks chunks selected for this module | 
					
						
							|  |  |  | 					 * @param {bigint | Chunk} selectedChunksKey a key of selectedChunks | 
					
						
							| 
									
										
										
										
											2018-05-17 18:35:13 +08:00
										 |  |  | 					 * @param {Module} module the current module | 
					
						
							|  |  |  | 					 * @returns {void} | 
					
						
							|  |  |  | 					 */ | 
					
						
							|  |  |  | 					const addModuleToChunksInfoMap = ( | 
					
						
							|  |  |  | 						cacheGroup, | 
					
						
							| 
									
										
										
										
											2020-07-13 16:12:17 +08:00
										 |  |  | 						cacheGroupIndex, | 
					
						
							| 
									
										
										
										
											2018-05-17 18:35:13 +08:00
										 |  |  | 						selectedChunks, | 
					
						
							| 
									
										
										
										
											2021-10-08 21:08:48 +08:00
										 |  |  | 						selectedChunksKey, | 
					
						
							| 
									
										
										
										
											2018-05-17 18:35:13 +08:00
										 |  |  | 						module | 
					
						
							|  |  |  | 					) => { | 
					
						
							|  |  |  | 						// Break if minimum number of chunks is not reached
 | 
					
						
							| 
									
										
										
										
											2021-10-08 21:08:48 +08:00
										 |  |  | 						if (selectedChunks.length < cacheGroup.minChunks) return; | 
					
						
							| 
									
										
										
										
											2018-05-17 18:35:13 +08:00
										 |  |  | 						// Determine name for split chunk
 | 
					
						
							|  |  |  | 						const name = cacheGroup.getName( | 
					
						
							|  |  |  | 							module, | 
					
						
							| 
									
										
										
										
											2021-10-08 21:08:48 +08:00
										 |  |  | 							selectedChunks, | 
					
						
							| 
									
										
										
										
											2018-05-17 18:35:13 +08:00
										 |  |  | 							cacheGroup.key | 
					
						
							|  |  |  | 						); | 
					
						
							| 
									
										
										
										
											2018-08-25 03:06:52 +08:00
										 |  |  | 						// Check if the name is ok
 | 
					
						
							| 
									
										
										
										
											2020-09-25 15:51:30 +08:00
										 |  |  | 						const existingChunk = compilation.namedChunks.get(name); | 
					
						
							|  |  |  | 						if (existingChunk) { | 
					
						
							| 
									
										
										
										
											2021-10-08 21:08:48 +08:00
										 |  |  | 							const parentValidationKey = `${name}|${ | 
					
						
							|  |  |  | 								typeof selectedChunksKey === "bigint" | 
					
						
							|  |  |  | 									? selectedChunksKey | 
					
						
							|  |  |  | 									: selectedChunksKey.debugId | 
					
						
							|  |  |  | 							}`;
 | 
					
						
							| 
									
										
										
										
											2020-09-25 15:51:30 +08:00
										 |  |  | 							const valid = alreadyValidatedParents.get(parentValidationKey); | 
					
						
							|  |  |  | 							if (valid === false) return; | 
					
						
							|  |  |  | 							if (valid === undefined) { | 
					
						
							|  |  |  | 								// Module can only be moved into the existing chunk if the existing chunk
 | 
					
						
							|  |  |  | 								// is a parent of all selected chunks
 | 
					
						
							|  |  |  | 								let isInAllParents = true; | 
					
						
							|  |  |  | 								/** @type {Set<ChunkGroup>} */ | 
					
						
							|  |  |  | 								const queue = new Set(); | 
					
						
							| 
									
										
										
										
											2021-10-08 21:08:48 +08:00
										 |  |  | 								for (const chunk of selectedChunks) { | 
					
						
							| 
									
										
										
										
											2020-09-25 15:51:30 +08:00
										 |  |  | 									for (const group of chunk.groupsIterable) { | 
					
						
							|  |  |  | 										queue.add(group); | 
					
						
							|  |  |  | 									} | 
					
						
							|  |  |  | 								} | 
					
						
							|  |  |  | 								for (const group of queue) { | 
					
						
							|  |  |  | 									if (existingChunk.isInGroup(group)) continue; | 
					
						
							|  |  |  | 									let hasParent = false; | 
					
						
							|  |  |  | 									for (const parent of group.parentsIterable) { | 
					
						
							|  |  |  | 										hasParent = true; | 
					
						
							|  |  |  | 										queue.add(parent); | 
					
						
							|  |  |  | 									} | 
					
						
							|  |  |  | 									if (!hasParent) { | 
					
						
							|  |  |  | 										isInAllParents = false; | 
					
						
							|  |  |  | 									} | 
					
						
							|  |  |  | 								} | 
					
						
							|  |  |  | 								const valid = isInAllParents; | 
					
						
							|  |  |  | 								alreadyValidatedParents.set(parentValidationKey, valid); | 
					
						
							|  |  |  | 								if (!valid) { | 
					
						
							|  |  |  | 									if (!alreadyReportedErrors.has(name)) { | 
					
						
							|  |  |  | 										alreadyReportedErrors.add(name); | 
					
						
							|  |  |  | 										compilation.errors.push( | 
					
						
							|  |  |  | 											new WebpackError( | 
					
						
							|  |  |  | 												"SplitChunksPlugin\n" + | 
					
						
							|  |  |  | 													`Cache group "${cacheGroup.key}" conflicts with existing chunk.\n` + | 
					
						
							|  |  |  | 													`Both have the same name "${name}" and existing chunk is not a parent of the selected modules.\n` + | 
					
						
							| 
									
										
										
										
											2021-08-24 22:15:17 +08:00
										 |  |  | 													"Use a different name for the cache group or make sure that the existing chunk is a parent (e. g. via dependOn).\n" + | 
					
						
							| 
									
										
										
										
											2020-09-25 15:51:30 +08:00
										 |  |  | 													'HINT: You can omit "name" to automatically create a name.\n' + | 
					
						
							|  |  |  | 													"BREAKING CHANGE: webpack < 5 used to allow to use an entrypoint as splitChunk. " + | 
					
						
							|  |  |  | 													"This is no longer allowed when the entrypoint is not a parent of the selected modules.\n" + | 
					
						
							|  |  |  | 													"Remove this entrypoint and add modules to cache group's 'test' instead. " + | 
					
						
							|  |  |  | 													"If you need modules to be evaluated on startup, add them to the existing entrypoints (make them arrays). " + | 
					
						
							|  |  |  | 													"See migration guide of more info." | 
					
						
							|  |  |  | 											) | 
					
						
							|  |  |  | 										); | 
					
						
							|  |  |  | 									} | 
					
						
							|  |  |  | 									return; | 
					
						
							|  |  |  | 								} | 
					
						
							| 
									
										
										
										
											2018-08-25 03:06:52 +08:00
										 |  |  | 							} | 
					
						
							|  |  |  | 						} | 
					
						
							| 
									
										
										
										
											2018-05-17 18:35:13 +08:00
										 |  |  | 						// Create key for maps
 | 
					
						
							|  |  |  | 						// When it has a name we use the name as key
 | 
					
						
							| 
									
										
										
										
											2020-03-13 00:51:26 +08:00
										 |  |  | 						// Otherwise we create the key from chunks and cache group key
 | 
					
						
							| 
									
										
										
										
											2018-05-17 18:35:13 +08:00
										 |  |  | 						// This automatically merges equal names
 | 
					
						
							|  |  |  | 						const key = | 
					
						
							| 
									
										
										
										
											2018-12-03 18:56:38 +08:00
										 |  |  | 							cacheGroup.key + | 
					
						
							| 
									
										
										
										
											2021-10-08 21:08:48 +08:00
										 |  |  | 							(name | 
					
						
							|  |  |  | 								? ` name:${name}` | 
					
						
							|  |  |  | 								: ` chunks:${keyToString(selectedChunksKey)}`); | 
					
						
							| 
									
										
										
										
											2018-05-17 18:35:13 +08:00
										 |  |  | 						// Add module to maps
 | 
					
						
							|  |  |  | 						let info = chunksInfoMap.get(key); | 
					
						
							|  |  |  | 						if (info === undefined) { | 
					
						
							|  |  |  | 							chunksInfoMap.set( | 
					
						
							|  |  |  | 								key, | 
					
						
							|  |  |  | 								(info = { | 
					
						
							| 
									
										
										
										
											2018-08-28 17:50:33 +08:00
										 |  |  | 									modules: new SortableSet( | 
					
						
							|  |  |  | 										undefined, | 
					
						
							|  |  |  | 										compareModulesByIdentifier | 
					
						
							|  |  |  | 									), | 
					
						
							| 
									
										
										
										
											2018-05-17 18:35:13 +08:00
										 |  |  | 									cacheGroup, | 
					
						
							| 
									
										
										
										
											2020-07-13 16:12:17 +08:00
										 |  |  | 									cacheGroupIndex, | 
					
						
							| 
									
										
										
										
											2018-05-17 18:35:13 +08:00
										 |  |  | 									name, | 
					
						
							| 
									
										
										
										
											2018-12-04 23:40:06 +08:00
										 |  |  | 									sizes: {}, | 
					
						
							| 
									
										
										
										
											2021-10-08 21:08:48 +08:00
										 |  |  | 									chunks: new Set(), | 
					
						
							| 
									
										
										
										
											2018-05-17 18:35:13 +08:00
										 |  |  | 									reuseableChunks: new Set(), | 
					
						
							| 
									
										
										
										
											2021-10-08 21:08:48 +08:00
										 |  |  | 									chunksKeys: new Set() | 
					
						
							| 
									
										
										
										
											2018-05-17 18:35:13 +08:00
										 |  |  | 								}) | 
					
						
							|  |  |  | 							); | 
					
						
							|  |  |  | 						} | 
					
						
							| 
									
										
										
										
											2021-01-07 23:51:08 +08:00
										 |  |  | 						const oldSize = info.modules.size; | 
					
						
							| 
									
										
										
										
											2018-05-17 18:35:13 +08:00
										 |  |  | 						info.modules.add(module); | 
					
						
							| 
									
										
										
										
											2021-01-07 23:51:08 +08:00
										 |  |  | 						if (info.modules.size !== oldSize) { | 
					
						
							|  |  |  | 							for (const type of module.getSourceTypes()) { | 
					
						
							|  |  |  | 								info.sizes[type] = (info.sizes[type] || 0) + module.size(type); | 
					
						
							|  |  |  | 							} | 
					
						
							| 
									
										
										
										
											2018-12-03 18:56:38 +08:00
										 |  |  | 						} | 
					
						
							| 
									
										
										
										
											2021-10-08 21:08:48 +08:00
										 |  |  | 						const oldChunksKeysSize = info.chunksKeys.size; | 
					
						
							|  |  |  | 						info.chunksKeys.add(selectedChunksKey); | 
					
						
							|  |  |  | 						if (oldChunksKeysSize !== info.chunksKeys.size) { | 
					
						
							|  |  |  | 							for (const chunk of selectedChunks) { | 
					
						
							|  |  |  | 								info.chunks.add(chunk); | 
					
						
							|  |  |  | 							} | 
					
						
							| 
									
										
										
										
											2018-05-17 18:35:13 +08:00
										 |  |  | 						} | 
					
						
							|  |  |  | 					}; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-08-14 17:18:22 +08:00
										 |  |  | 					const context = { | 
					
						
							|  |  |  | 						moduleGraph, | 
					
						
							|  |  |  | 						chunkGraph | 
					
						
							|  |  |  | 					}; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-25 21:46:08 +08:00
										 |  |  | 					logger.timeEnd("prepare"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					logger.time("modules"); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 					// Walk through all modules
 | 
					
						
							|  |  |  | 					for (const module of compilation.modules) { | 
					
						
							|  |  |  | 						// Get cache group
 | 
					
						
							| 
									
										
										
										
											2018-08-14 17:18:22 +08:00
										 |  |  | 						let cacheGroups = this.options.getCacheGroups(module, context); | 
					
						
							| 
									
										
										
										
											2018-05-29 20:50:40 +08:00
										 |  |  | 						if (!Array.isArray(cacheGroups) || cacheGroups.length === 0) { | 
					
						
							| 
									
										
										
										
											2018-04-27 20:29:34 +08:00
										 |  |  | 							continue; | 
					
						
							| 
									
										
										
										
											2018-05-29 20:50:40 +08:00
										 |  |  | 						} | 
					
						
							| 
									
										
										
										
											2018-04-27 20:29:34 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-08 21:08:48 +08:00
										 |  |  | 						// Prepare some values (usedExports = false)
 | 
					
						
							|  |  |  | 						const getCombs = memoize(() => { | 
					
						
							|  |  |  | 							const chunks = chunkGraph.getModuleChunksIterable(module); | 
					
						
							|  |  |  | 							const chunksKey = getKey(chunks); | 
					
						
							|  |  |  | 							return getCombinations(chunksKey); | 
					
						
							|  |  |  | 						}); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 						// Prepare some values (usedExports = true)
 | 
					
						
							|  |  |  | 						const getCombsByUsedExports = memoize(() => { | 
					
						
							|  |  |  | 							// fill the groupedByExportsMap
 | 
					
						
							|  |  |  | 							getExportsChunkSetsInGraph(); | 
					
						
							|  |  |  | 							/** @type {Set<Set<Chunk> | Chunk>} */ | 
					
						
							|  |  |  | 							const set = new Set(); | 
					
						
							|  |  |  | 							const groupedByUsedExports = groupedByExportsMap.get(module); | 
					
						
							|  |  |  | 							for (const chunks of groupedByUsedExports) { | 
					
						
							|  |  |  | 								const chunksKey = getKey(chunks); | 
					
						
							|  |  |  | 								for (const comb of getExportsCombinations(chunksKey)) | 
					
						
							|  |  |  | 									set.add(comb); | 
					
						
							|  |  |  | 							} | 
					
						
							|  |  |  | 							return set; | 
					
						
							|  |  |  | 						}); | 
					
						
							| 
									
										
										
										
											2018-04-27 20:29:34 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-13 16:12:17 +08:00
										 |  |  | 						let cacheGroupIndex = 0; | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 						for (const cacheGroupSource of cacheGroups) { | 
					
						
							| 
									
										
										
										
											2020-07-28 00:09:48 +08:00
										 |  |  | 							const cacheGroup = this._getCacheGroup(cacheGroupSource); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-08 21:08:48 +08:00
										 |  |  | 							const combs = cacheGroup.usedExports | 
					
						
							|  |  |  | 								? getCombsByUsedExports() | 
					
						
							|  |  |  | 								: getCombs(); | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 							// For all combination of chunk selection
 | 
					
						
							| 
									
										
										
										
											2021-10-08 21:08:48 +08:00
										 |  |  | 							for (const chunkCombination of combs) { | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 								// Break if minimum number of chunks is not reached
 | 
					
						
							| 
									
										
										
										
											2021-10-08 21:08:48 +08:00
										 |  |  | 								const count = | 
					
						
							|  |  |  | 									chunkCombination instanceof Chunk ? 1 : chunkCombination.size; | 
					
						
							| 
									
										
										
										
											2020-08-13 22:54:24 +08:00
										 |  |  | 								if (count < cacheGroup.minChunks) continue; | 
					
						
							| 
									
										
										
										
											2021-10-08 21:08:48 +08:00
										 |  |  | 								// Select chunks by configuration
 | 
					
						
							|  |  |  | 								const { chunks: selectedChunks, key: selectedChunksKey } = | 
					
						
							|  |  |  | 									getSelectedChunks(chunkCombination, cacheGroup.chunksFilter); | 
					
						
							| 
									
										
										
										
											2018-05-17 18:35:13 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-06 02:38:10 +08:00
										 |  |  | 								addModuleToChunksInfoMap( | 
					
						
							|  |  |  | 									cacheGroup, | 
					
						
							| 
									
										
										
										
											2020-07-13 16:12:17 +08:00
										 |  |  | 									cacheGroupIndex, | 
					
						
							| 
									
										
										
										
											2018-12-06 02:38:10 +08:00
										 |  |  | 									selectedChunks, | 
					
						
							| 
									
										
										
										
											2021-10-08 21:08:48 +08:00
										 |  |  | 									selectedChunksKey, | 
					
						
							| 
									
										
										
										
											2018-12-06 02:38:10 +08:00
										 |  |  | 									module | 
					
						
							|  |  |  | 								); | 
					
						
							| 
									
										
										
										
											2018-01-20 00:06:59 +08:00
										 |  |  | 							} | 
					
						
							| 
									
										
										
										
											2020-07-13 16:12:17 +08:00
										 |  |  | 							cacheGroupIndex++; | 
					
						
							| 
									
										
										
										
											2018-01-20 00:06:59 +08:00
										 |  |  | 						} | 
					
						
							|  |  |  | 					} | 
					
						
							| 
									
										
										
										
											2018-04-27 20:29:34 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-25 21:46:08 +08:00
										 |  |  | 					logger.timeEnd("modules"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					logger.time("queue"); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-25 22:16:05 +08:00
										 |  |  | 					/** | 
					
						
							|  |  |  | 					 * @param {ChunksInfoItem} info entry | 
					
						
							|  |  |  | 					 * @param {string[]} sourceTypes source types to be removed | 
					
						
							|  |  |  | 					 */ | 
					
						
							|  |  |  | 					const removeModulesWithSourceType = (info, sourceTypes) => { | 
					
						
							|  |  |  | 						for (const module of info.modules) { | 
					
						
							|  |  |  | 							const types = module.getSourceTypes(); | 
					
						
							|  |  |  | 							if (sourceTypes.some(type => types.has(type))) { | 
					
						
							|  |  |  | 								info.modules.delete(module); | 
					
						
							|  |  |  | 								for (const type of types) { | 
					
						
							|  |  |  | 									info.sizes[type] -= module.size(type); | 
					
						
							|  |  |  | 								} | 
					
						
							|  |  |  | 							} | 
					
						
							|  |  |  | 						} | 
					
						
							|  |  |  | 					}; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					/** | 
					
						
							|  |  |  | 					 * @param {ChunksInfoItem} info entry | 
					
						
							|  |  |  | 					 * @returns {boolean} true, if entry become empty | 
					
						
							|  |  |  | 					 */ | 
					
						
							|  |  |  | 					const removeMinSizeViolatingModules = info => { | 
					
						
							|  |  |  | 						if (!info.cacheGroup._validateSize) return false; | 
					
						
							|  |  |  | 						const violatingSizes = getViolatingMinSizes( | 
					
						
							|  |  |  | 							info.sizes, | 
					
						
							|  |  |  | 							info.cacheGroup.minSize | 
					
						
							|  |  |  | 						); | 
					
						
							|  |  |  | 						if (violatingSizes === undefined) return false; | 
					
						
							|  |  |  | 						removeModulesWithSourceType(info, violatingSizes); | 
					
						
							|  |  |  | 						return info.modules.size === 0; | 
					
						
							|  |  |  | 					}; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-03 18:56:38 +08:00
										 |  |  | 					// Filter items were size < minSize
 | 
					
						
							| 
									
										
										
										
											2020-07-13 16:12:17 +08:00
										 |  |  | 					for (const [key, info] of chunksInfoMap) { | 
					
						
							| 
									
										
										
										
											2020-09-25 22:16:05 +08:00
										 |  |  | 						if (removeMinSizeViolatingModules(info)) { | 
					
						
							| 
									
										
										
										
											2020-07-13 16:12:17 +08:00
										 |  |  | 							chunksInfoMap.delete(key); | 
					
						
							| 
									
										
										
										
											2021-10-19 15:42:57 +08:00
										 |  |  | 						} else if ( | 
					
						
							|  |  |  | 							!checkMinSizeReduction( | 
					
						
							|  |  |  | 								info.sizes, | 
					
						
							|  |  |  | 								info.cacheGroup.minSizeReduction, | 
					
						
							|  |  |  | 								info.chunks.size | 
					
						
							|  |  |  | 							) | 
					
						
							|  |  |  | 						) { | 
					
						
							|  |  |  | 							chunksInfoMap.delete(key); | 
					
						
							| 
									
										
										
										
											2018-12-03 18:56:38 +08:00
										 |  |  | 						} | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-11 04:19:10 +08:00
										 |  |  | 					/** | 
					
						
							|  |  |  | 					 * @typedef {Object} MaxSizeQueueItem | 
					
						
							|  |  |  | 					 * @property {SplitChunksSizes} minSize | 
					
						
							| 
									
										
										
										
											2018-12-12 03:47:50 +08:00
										 |  |  | 					 * @property {SplitChunksSizes} maxAsyncSize | 
					
						
							|  |  |  | 					 * @property {SplitChunksSizes} maxInitialSize | 
					
						
							| 
									
										
										
										
											2018-12-11 04:19:10 +08:00
										 |  |  | 					 * @property {string} automaticNameDelimiter | 
					
						
							|  |  |  | 					 * @property {string[]} keys | 
					
						
							|  |  |  | 					 */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					/** @type {Map<Chunk, MaxSizeQueueItem>} */ | 
					
						
							| 
									
										
										
										
											2018-07-04 15:59:22 +08:00
										 |  |  | 					const maxSizeQueueMap = new Map(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 					while (chunksInfoMap.size > 0) { | 
					
						
							|  |  |  | 						// Find best matching entry
 | 
					
						
							|  |  |  | 						let bestEntryKey; | 
					
						
							|  |  |  | 						let bestEntry; | 
					
						
							|  |  |  | 						for (const pair of chunksInfoMap) { | 
					
						
							|  |  |  | 							const key = pair[0]; | 
					
						
							|  |  |  | 							const info = pair[1]; | 
					
						
							| 
									
										
										
										
											2019-06-15 19:31:45 +08:00
										 |  |  | 							if ( | 
					
						
							|  |  |  | 								bestEntry === undefined || | 
					
						
							|  |  |  | 								compareEntries(bestEntry, info) < 0 | 
					
						
							|  |  |  | 							) { | 
					
						
							| 
									
										
										
										
											2018-12-03 18:56:38 +08:00
										 |  |  | 								bestEntry = info; | 
					
						
							|  |  |  | 								bestEntryKey = key; | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 							} | 
					
						
							|  |  |  | 						} | 
					
						
							| 
									
										
										
										
											2018-01-20 00:06:59 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 						const item = bestEntry; | 
					
						
							|  |  |  | 						chunksInfoMap.delete(bestEntryKey); | 
					
						
							| 
									
										
										
										
											2018-01-20 00:06:59 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 						let chunkName = item.name; | 
					
						
							|  |  |  | 						// Variable for the new chunk (lazy created)
 | 
					
						
							| 
									
										
										
										
											2018-07-04 15:59:22 +08:00
										 |  |  | 						/** @type {Chunk} */ | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 						let newChunk; | 
					
						
							|  |  |  | 						// When no chunk name, check if we can reuse a chunk instead of creating a new one
 | 
					
						
							| 
									
										
										
										
											2019-06-18 20:28:57 +08:00
										 |  |  | 						let isExistingChunk = false; | 
					
						
							|  |  |  | 						let isReusedWithAllModules = false; | 
					
						
							| 
									
										
										
										
											2019-05-10 03:34:28 +08:00
										 |  |  | 						if (chunkName) { | 
					
						
							|  |  |  | 							const chunkByName = compilation.namedChunks.get(chunkName); | 
					
						
							|  |  |  | 							if (chunkByName !== undefined) { | 
					
						
							|  |  |  | 								newChunk = chunkByName; | 
					
						
							| 
									
										
										
										
											2021-10-08 21:08:48 +08:00
										 |  |  | 								const oldSize = item.chunks.size; | 
					
						
							|  |  |  | 								item.chunks.delete(newChunk); | 
					
						
							|  |  |  | 								isExistingChunk = item.chunks.size !== oldSize; | 
					
						
							| 
									
										
										
										
											2019-05-10 03:34:28 +08:00
										 |  |  | 							} | 
					
						
							|  |  |  | 						} else if (item.cacheGroup.reuseExistingChunk) { | 
					
						
							| 
									
										
										
										
											2021-10-08 21:08:48 +08:00
										 |  |  | 							outer: for (const chunk of item.chunks) { | 
					
						
							| 
									
										
										
										
											2018-08-14 17:18:22 +08:00
										 |  |  | 								if ( | 
					
						
							|  |  |  | 									chunkGraph.getNumberOfChunkModules(chunk) !== | 
					
						
							|  |  |  | 									item.modules.size | 
					
						
							| 
									
										
										
										
											2018-12-12 03:47:50 +08:00
										 |  |  | 								) { | 
					
						
							|  |  |  | 									continue; | 
					
						
							|  |  |  | 								} | 
					
						
							| 
									
										
										
										
											2021-01-20 00:08:58 +08:00
										 |  |  | 								if ( | 
					
						
							|  |  |  | 									item.chunks.size > 1 && | 
					
						
							|  |  |  | 									chunkGraph.getNumberOfEntryModules(chunk) > 0 | 
					
						
							|  |  |  | 								) { | 
					
						
							| 
									
										
										
										
											2018-08-14 17:18:22 +08:00
										 |  |  | 									continue; | 
					
						
							| 
									
										
										
										
											2018-12-12 03:47:50 +08:00
										 |  |  | 								} | 
					
						
							| 
									
										
										
										
											2018-06-20 00:21:09 +08:00
										 |  |  | 								for (const module of item.modules) { | 
					
						
							| 
									
										
										
										
											2018-12-12 03:47:50 +08:00
										 |  |  | 									if (!chunkGraph.isModuleInChunk(module, chunk)) { | 
					
						
							| 
									
										
										
										
											2018-08-14 17:18:22 +08:00
										 |  |  | 										continue outer; | 
					
						
							| 
									
										
										
										
											2018-12-12 03:47:50 +08:00
										 |  |  | 									} | 
					
						
							| 
									
										
										
										
											2018-06-20 00:21:09 +08:00
										 |  |  | 								} | 
					
						
							|  |  |  | 								if (!newChunk || !newChunk.name) { | 
					
						
							|  |  |  | 									newChunk = chunk; | 
					
						
							|  |  |  | 								} else if ( | 
					
						
							|  |  |  | 									chunk.name && | 
					
						
							|  |  |  | 									chunk.name.length < newChunk.name.length | 
					
						
							|  |  |  | 								) { | 
					
						
							|  |  |  | 									newChunk = chunk; | 
					
						
							|  |  |  | 								} else if ( | 
					
						
							|  |  |  | 									chunk.name && | 
					
						
							|  |  |  | 									chunk.name.length === newChunk.name.length && | 
					
						
							|  |  |  | 									chunk.name < newChunk.name | 
					
						
							|  |  |  | 								) { | 
					
						
							|  |  |  | 									newChunk = chunk; | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 								} | 
					
						
							| 
									
										
										
										
											2019-05-10 03:34:28 +08:00
										 |  |  | 							} | 
					
						
							|  |  |  | 							if (newChunk) { | 
					
						
							| 
									
										
										
										
											2021-10-08 21:08:48 +08:00
										 |  |  | 								item.chunks.delete(newChunk); | 
					
						
							| 
									
										
										
										
											2018-06-20 00:21:09 +08:00
										 |  |  | 								chunkName = undefined; | 
					
						
							| 
									
										
										
										
											2019-06-18 20:28:57 +08:00
										 |  |  | 								isExistingChunk = true; | 
					
						
							|  |  |  | 								isReusedWithAllModules = true; | 
					
						
							| 
									
										
										
										
											2018-01-20 00:06:59 +08:00
										 |  |  | 							} | 
					
						
							|  |  |  | 						} | 
					
						
							| 
									
										
										
										
											2018-05-17 18:35:13 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-13 16:12:17 +08:00
										 |  |  | 						const enforced = | 
					
						
							|  |  |  | 							item.cacheGroup._conditionalEnforce && | 
					
						
							|  |  |  | 							checkMinSize(item.sizes, item.cacheGroup.enforceSizeThreshold); | 
					
						
							| 
									
										
										
										
											2018-05-17 18:35:13 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-08 21:08:48 +08:00
										 |  |  | 						const usedChunks = new Set(item.chunks); | 
					
						
							| 
									
										
										
										
											2018-05-17 18:35:13 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-13 16:12:17 +08:00
										 |  |  | 						// Check if maxRequests condition can be fulfilled
 | 
					
						
							| 
									
										
										
										
											2018-12-03 18:56:38 +08:00
										 |  |  | 						if ( | 
					
						
							| 
									
										
										
										
											2020-07-13 16:12:17 +08:00
										 |  |  | 							!enforced && | 
					
						
							|  |  |  | 							(Number.isFinite(item.cacheGroup.maxInitialRequests) || | 
					
						
							|  |  |  | 								Number.isFinite(item.cacheGroup.maxAsyncRequests)) | 
					
						
							| 
									
										
										
										
											2018-12-03 18:56:38 +08:00
										 |  |  | 						) { | 
					
						
							| 
									
										
										
										
											2021-10-08 21:08:48 +08:00
										 |  |  | 							for (const chunk of usedChunks) { | 
					
						
							| 
									
										
										
										
											2020-07-13 16:12:17 +08:00
										 |  |  | 								// respect max requests
 | 
					
						
							| 
									
										
										
										
											2018-12-03 18:56:38 +08:00
										 |  |  | 								const maxRequests = chunk.isOnlyInitial() | 
					
						
							|  |  |  | 									? item.cacheGroup.maxInitialRequests | 
					
						
							|  |  |  | 									: chunk.canBeInitial() | 
					
						
							| 
									
										
										
										
											2019-02-05 17:06:32 +08:00
										 |  |  | 									? Math.min( | 
					
						
							|  |  |  | 											item.cacheGroup.maxInitialRequests, | 
					
						
							|  |  |  | 											item.cacheGroup.maxAsyncRequests | 
					
						
							|  |  |  | 									  ) | 
					
						
							|  |  |  | 									: item.cacheGroup.maxAsyncRequests; | 
					
						
							| 
									
										
										
										
											2020-07-13 16:12:17 +08:00
										 |  |  | 								if ( | 
					
						
							|  |  |  | 									isFinite(maxRequests) && | 
					
						
							|  |  |  | 									getRequests(chunk) >= maxRequests | 
					
						
							|  |  |  | 								) { | 
					
						
							| 
									
										
										
										
											2021-10-08 21:08:48 +08:00
										 |  |  | 									usedChunks.delete(chunk); | 
					
						
							| 
									
										
										
										
											2020-07-13 16:12:17 +08:00
										 |  |  | 								} | 
					
						
							|  |  |  | 							} | 
					
						
							| 
									
										
										
										
											2019-03-15 19:39:21 +08:00
										 |  |  | 						} | 
					
						
							| 
									
										
										
										
											2018-12-03 18:56:38 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-08 21:08:48 +08:00
										 |  |  | 						outer: for (const chunk of usedChunks) { | 
					
						
							| 
									
										
										
										
											2019-06-12 14:58:17 +08:00
										 |  |  | 							for (const module of item.modules) { | 
					
						
							| 
									
										
										
										
											2020-07-13 16:12:17 +08:00
										 |  |  | 								if (chunkGraph.isModuleInChunk(module, chunk)) continue outer; | 
					
						
							| 
									
										
										
										
											2019-06-11 23:46:36 +08:00
										 |  |  | 							} | 
					
						
							| 
									
										
										
										
											2021-10-08 21:08:48 +08:00
										 |  |  | 							usedChunks.delete(chunk); | 
					
						
							| 
									
										
										
										
											2020-07-13 16:12:17 +08:00
										 |  |  | 						} | 
					
						
							| 
									
										
										
										
											2019-03-15 19:39:21 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-13 16:12:17 +08:00
										 |  |  | 						// Were some (invalid) chunks removed from usedChunks?
 | 
					
						
							|  |  |  | 						// => readd all modules to the queue, as things could have been changed
 | 
					
						
							| 
									
										
										
										
											2021-10-08 21:08:48 +08:00
										 |  |  | 						if (usedChunks.size < item.chunks.size) { | 
					
						
							|  |  |  | 							if (isExistingChunk) usedChunks.add(newChunk); | 
					
						
							| 
									
										
										
										
											2020-07-13 16:12:17 +08:00
										 |  |  | 							if (usedChunks.size >= item.cacheGroup.minChunks) { | 
					
						
							| 
									
										
										
										
											2021-10-08 21:08:48 +08:00
										 |  |  | 								const chunksArr = Array.from(usedChunks); | 
					
						
							| 
									
										
										
										
											2019-03-15 19:39:21 +08:00
										 |  |  | 								for (const module of item.modules) { | 
					
						
							|  |  |  | 									addModuleToChunksInfoMap( | 
					
						
							|  |  |  | 										item.cacheGroup, | 
					
						
							| 
									
										
										
										
											2020-07-13 16:12:17 +08:00
										 |  |  | 										item.cacheGroupIndex, | 
					
						
							| 
									
										
										
										
											2021-10-08 21:08:48 +08:00
										 |  |  | 										chunksArr, | 
					
						
							|  |  |  | 										getKey(usedChunks), | 
					
						
							| 
									
										
										
										
											2019-03-15 19:39:21 +08:00
										 |  |  | 										module | 
					
						
							|  |  |  | 									); | 
					
						
							| 
									
										
										
										
											2018-12-03 18:56:38 +08:00
										 |  |  | 								} | 
					
						
							| 
									
										
										
										
											2018-01-20 00:06:59 +08:00
										 |  |  | 							} | 
					
						
							| 
									
										
										
										
											2019-03-15 19:39:21 +08:00
										 |  |  | 							continue; | 
					
						
							| 
									
										
										
										
											2018-05-17 18:35:13 +08:00
										 |  |  | 						} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-12 14:58:17 +08:00
										 |  |  | 						// Validate minRemainingSize constraint when a single chunk is left over
 | 
					
						
							|  |  |  | 						if ( | 
					
						
							| 
									
										
										
										
											2020-07-13 16:12:17 +08:00
										 |  |  | 							!enforced && | 
					
						
							|  |  |  | 							item.cacheGroup._validateRemainingSize && | 
					
						
							|  |  |  | 							usedChunks.size === 1 | 
					
						
							| 
									
										
										
										
											2019-06-12 14:58:17 +08:00
										 |  |  | 						) { | 
					
						
							| 
									
										
										
										
											2021-10-08 21:08:48 +08:00
										 |  |  | 							const [chunk] = usedChunks; | 
					
						
							| 
									
										
										
										
											2020-07-13 16:12:17 +08:00
										 |  |  | 							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); | 
					
						
							|  |  |  | 									} | 
					
						
							|  |  |  | 								} | 
					
						
							| 
									
										
										
										
											2019-06-12 14:58:17 +08:00
										 |  |  | 							} | 
					
						
							| 
									
										
										
										
											2020-09-25 22:16:05 +08:00
										 |  |  | 							const violatingSizes = getViolatingMinSizes( | 
					
						
							|  |  |  | 								chunkSizes, | 
					
						
							|  |  |  | 								item.cacheGroup.minRemainingSize | 
					
						
							|  |  |  | 							); | 
					
						
							|  |  |  | 							if (violatingSizes !== undefined) { | 
					
						
							|  |  |  | 								const oldModulesSize = item.modules.size; | 
					
						
							|  |  |  | 								removeModulesWithSourceType(item, violatingSizes); | 
					
						
							|  |  |  | 								if ( | 
					
						
							|  |  |  | 									item.modules.size > 0 && | 
					
						
							|  |  |  | 									item.modules.size !== oldModulesSize | 
					
						
							|  |  |  | 								) { | 
					
						
							|  |  |  | 									// queue this item again to be processed again
 | 
					
						
							|  |  |  | 									// without violating modules
 | 
					
						
							|  |  |  | 									chunksInfoMap.set(bestEntryKey, item); | 
					
						
							|  |  |  | 								} | 
					
						
							| 
									
										
										
										
											2019-06-12 14:58:17 +08:00
										 |  |  | 								continue; | 
					
						
							|  |  |  | 							} | 
					
						
							|  |  |  | 						} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-17 18:35:13 +08:00
										 |  |  | 						// Create the new chunk if not reusing one
 | 
					
						
							| 
									
										
										
										
											2020-08-19 20:40:01 +08:00
										 |  |  | 						if (newChunk === undefined) { | 
					
						
							| 
									
										
										
										
											2018-05-17 18:35:13 +08:00
										 |  |  | 							newChunk = compilation.addChunk(chunkName); | 
					
						
							|  |  |  | 						} | 
					
						
							|  |  |  | 						// Walk through all chunks
 | 
					
						
							| 
									
										
										
										
											2021-10-08 21:08:48 +08:00
										 |  |  | 						for (const chunk of usedChunks) { | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 							// Add graph connections for splitted chunk
 | 
					
						
							|  |  |  | 							chunk.split(newChunk); | 
					
						
							| 
									
										
										
										
											2018-01-20 00:06:59 +08:00
										 |  |  | 						} | 
					
						
							| 
									
										
										
										
											2018-04-27 20:29:34 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-17 18:35:13 +08:00
										 |  |  | 						// Add a note to the chunk
 | 
					
						
							| 
									
										
										
										
											2019-06-18 20:28:57 +08:00
										 |  |  | 						newChunk.chunkReason = | 
					
						
							|  |  |  | 							(newChunk.chunkReason ? newChunk.chunkReason + ", " : "") + | 
					
						
							|  |  |  | 							(isReusedWithAllModules | 
					
						
							|  |  |  | 								? "reused as split chunk" | 
					
						
							|  |  |  | 								: "split chunk"); | 
					
						
							| 
									
										
										
										
											2018-05-17 18:35:13 +08:00
										 |  |  | 						if (item.cacheGroup.key) { | 
					
						
							|  |  |  | 							newChunk.chunkReason += ` (cache group: ${item.cacheGroup.key})`; | 
					
						
							|  |  |  | 						} | 
					
						
							|  |  |  | 						if (chunkName) { | 
					
						
							|  |  |  | 							newChunk.chunkReason += ` (name: ${chunkName})`; | 
					
						
							|  |  |  | 						} | 
					
						
							|  |  |  | 						if (item.cacheGroup.filename) { | 
					
						
							|  |  |  | 							newChunk.filenameTemplate = item.cacheGroup.filename; | 
					
						
							|  |  |  | 						} | 
					
						
							| 
									
										
										
										
											2018-12-07 19:26:35 +08:00
										 |  |  | 						if (item.cacheGroup.idHint) { | 
					
						
							|  |  |  | 							newChunk.idNameHints.add(item.cacheGroup.idHint); | 
					
						
							|  |  |  | 						} | 
					
						
							| 
									
										
										
										
											2019-06-18 20:28:57 +08:00
										 |  |  | 						if (!isReusedWithAllModules) { | 
					
						
							| 
									
										
										
										
											2018-05-17 18:35:13 +08:00
										 |  |  | 							// Add all modules to the new chunk
 | 
					
						
							|  |  |  | 							for (const module of item.modules) { | 
					
						
							| 
									
										
										
										
											2018-08-14 22:40:37 +08:00
										 |  |  | 								if (!module.chunkCondition(newChunk, compilation)) continue; | 
					
						
							| 
									
										
										
										
											2018-05-17 18:35:13 +08:00
										 |  |  | 								// Add module to new chunk
 | 
					
						
							| 
									
										
										
										
											2018-08-14 17:18:22 +08:00
										 |  |  | 								chunkGraph.connectChunkAndModule(newChunk, module); | 
					
						
							| 
									
										
										
										
											2018-05-17 18:35:13 +08:00
										 |  |  | 								// Remove module from used chunks
 | 
					
						
							| 
									
										
										
										
											2021-10-08 21:08:48 +08:00
										 |  |  | 								for (const chunk of usedChunks) { | 
					
						
							| 
									
										
										
										
											2018-08-14 17:18:22 +08:00
										 |  |  | 									chunkGraph.disconnectChunkAndModule(chunk, module); | 
					
						
							| 
									
										
										
										
											2018-01-20 00:06:59 +08:00
										 |  |  | 								} | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 							} | 
					
						
							| 
									
										
										
										
											2018-05-17 18:35:13 +08:00
										 |  |  | 						} else { | 
					
						
							|  |  |  | 							// Remove all modules from used chunks
 | 
					
						
							|  |  |  | 							for (const module of item.modules) { | 
					
						
							| 
									
										
										
										
											2021-10-08 21:08:48 +08:00
										 |  |  | 								for (const chunk of usedChunks) { | 
					
						
							| 
									
										
										
										
											2018-08-14 17:18:22 +08:00
										 |  |  | 									chunkGraph.disconnectChunkAndModule(chunk, module); | 
					
						
							| 
									
										
										
										
											2018-03-02 17:14:25 +08:00
										 |  |  | 								} | 
					
						
							|  |  |  | 							} | 
					
						
							| 
									
										
										
										
											2018-05-17 18:35:13 +08:00
										 |  |  | 						} | 
					
						
							| 
									
										
										
										
											2018-07-04 15:59:22 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-12 03:47:50 +08:00
										 |  |  | 						if ( | 
					
						
							|  |  |  | 							Object.keys(item.cacheGroup.maxAsyncSize).length > 0 || | 
					
						
							|  |  |  | 							Object.keys(item.cacheGroup.maxInitialSize).length > 0 | 
					
						
							|  |  |  | 						) { | 
					
						
							| 
									
										
										
										
											2018-07-04 15:59:22 +08:00
										 |  |  | 							const oldMaxSizeSettings = maxSizeQueueMap.get(newChunk); | 
					
						
							|  |  |  | 							maxSizeQueueMap.set(newChunk, { | 
					
						
							| 
									
										
										
										
											2018-12-04 23:40:06 +08:00
										 |  |  | 								minSize: oldMaxSizeSettings | 
					
						
							|  |  |  | 									? combineSizes( | 
					
						
							|  |  |  | 											oldMaxSizeSettings.minSize, | 
					
						
							| 
									
										
										
										
											2020-07-13 16:12:17 +08:00
										 |  |  | 											item.cacheGroup._minSizeForMaxSize, | 
					
						
							| 
									
										
										
										
											2018-12-04 23:40:06 +08:00
										 |  |  | 											Math.max | 
					
						
							|  |  |  | 									  ) | 
					
						
							|  |  |  | 									: item.cacheGroup.minSize, | 
					
						
							| 
									
										
										
										
											2018-12-12 03:47:50 +08:00
										 |  |  | 								maxAsyncSize: oldMaxSizeSettings | 
					
						
							| 
									
										
										
										
											2018-12-04 23:40:06 +08:00
										 |  |  | 									? combineSizes( | 
					
						
							| 
									
										
										
										
											2018-12-12 03:47:50 +08:00
										 |  |  | 											oldMaxSizeSettings.maxAsyncSize, | 
					
						
							|  |  |  | 											item.cacheGroup.maxAsyncSize, | 
					
						
							| 
									
										
										
										
											2018-12-04 23:40:06 +08:00
										 |  |  | 											Math.min | 
					
						
							|  |  |  | 									  ) | 
					
						
							| 
									
										
										
										
											2018-12-12 03:47:50 +08:00
										 |  |  | 									: item.cacheGroup.maxAsyncSize, | 
					
						
							|  |  |  | 								maxInitialSize: oldMaxSizeSettings | 
					
						
							|  |  |  | 									? combineSizes( | 
					
						
							|  |  |  | 											oldMaxSizeSettings.maxInitialSize, | 
					
						
							|  |  |  | 											item.cacheGroup.maxInitialSize, | 
					
						
							|  |  |  | 											Math.min | 
					
						
							|  |  |  | 									  ) | 
					
						
							|  |  |  | 									: item.cacheGroup.maxInitialSize, | 
					
						
							| 
									
										
										
										
											2018-12-03 18:56:38 +08:00
										 |  |  | 								automaticNameDelimiter: item.cacheGroup.automaticNameDelimiter, | 
					
						
							|  |  |  | 								keys: oldMaxSizeSettings | 
					
						
							|  |  |  | 									? oldMaxSizeSettings.keys.concat(item.cacheGroup.key) | 
					
						
							|  |  |  | 									: [item.cacheGroup.key] | 
					
						
							| 
									
										
										
										
											2018-07-04 15:59:22 +08:00
										 |  |  | 							}); | 
					
						
							|  |  |  | 						} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-17 18:35:13 +08:00
										 |  |  | 						// remove all modules from other entries and update size
 | 
					
						
							|  |  |  | 						for (const [key, info] of chunksInfoMap) { | 
					
						
							| 
									
										
										
										
											2021-10-08 21:08:48 +08:00
										 |  |  | 							if (isOverlap(info.chunks, usedChunks)) { | 
					
						
							| 
									
										
										
										
											2020-07-13 16:12:17 +08:00
										 |  |  | 								// 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
 | 
					
						
							| 
									
										
										
										
											2018-12-03 18:56:38 +08:00
										 |  |  | 										info.modules.delete(module); | 
					
						
							| 
									
										
										
										
											2020-07-13 16:12:17 +08:00
										 |  |  | 										// update size
 | 
					
						
							|  |  |  | 										for (const key of module.getSourceTypes()) { | 
					
						
							|  |  |  | 											info.sizes[key] -= module.size(key); | 
					
						
							|  |  |  | 										} | 
					
						
							|  |  |  | 										updated = true; | 
					
						
							| 
									
										
										
										
											2018-12-03 18:56:38 +08:00
										 |  |  | 									} | 
					
						
							| 
									
										
										
										
											2020-07-13 16:12:17 +08:00
										 |  |  | 								} | 
					
						
							|  |  |  | 								if (updated) { | 
					
						
							| 
									
										
										
										
											2018-12-03 18:56:38 +08:00
										 |  |  | 									if (info.modules.size === 0) { | 
					
						
							| 
									
										
										
										
											2018-02-16 16:12:01 +08:00
										 |  |  | 										chunksInfoMap.delete(key); | 
					
						
							| 
									
										
										
										
											2020-07-13 16:12:17 +08:00
										 |  |  | 										continue; | 
					
						
							|  |  |  | 									} | 
					
						
							| 
									
										
										
										
											2021-10-19 15:42:57 +08:00
										 |  |  | 									if ( | 
					
						
							|  |  |  | 										removeMinSizeViolatingModules(info) || | 
					
						
							|  |  |  | 										!checkMinSizeReduction( | 
					
						
							|  |  |  | 											info.sizes, | 
					
						
							|  |  |  | 											info.cacheGroup.minSizeReduction, | 
					
						
							|  |  |  | 											info.chunks.size | 
					
						
							|  |  |  | 										) | 
					
						
							|  |  |  | 									) { | 
					
						
							| 
									
										
										
										
											2020-07-13 16:12:17 +08:00
										 |  |  | 										chunksInfoMap.delete(key); | 
					
						
							| 
									
										
										
										
											2020-09-25 22:16:05 +08:00
										 |  |  | 										continue; | 
					
						
							| 
									
										
										
										
											2018-05-29 20:50:40 +08:00
										 |  |  | 									} | 
					
						
							| 
									
										
										
										
											2018-01-20 00:06:59 +08:00
										 |  |  | 								} | 
					
						
							|  |  |  | 							} | 
					
						
							|  |  |  | 						} | 
					
						
							|  |  |  | 					} | 
					
						
							| 
									
										
										
										
											2018-07-04 15:59:22 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-25 21:46:08 +08:00
										 |  |  | 					logger.timeEnd("queue"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					logger.time("maxSize"); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-11 04:19:10 +08:00
										 |  |  | 					/** @type {Set<string>} */ | 
					
						
							| 
									
										
										
										
											2018-12-03 18:56:38 +08:00
										 |  |  | 					const incorrectMinMaxSizeSet = new Set(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-04 16:18:54 +08:00
										 |  |  | 					const { outputOptions } = compilation; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-04 15:59:22 +08:00
										 |  |  | 					// Make sure that maxSize is fulfilled
 | 
					
						
							| 
									
										
										
										
											2021-11-02 20:23:09 +08:00
										 |  |  | 					const { fallbackCacheGroup } = this.options; | 
					
						
							| 
									
										
										
										
											2018-09-06 22:59:11 +08:00
										 |  |  | 					for (const chunk of Array.from(compilation.chunks)) { | 
					
						
							| 
									
										
										
										
											2018-12-04 18:02:26 +08:00
										 |  |  | 						const chunkConfig = maxSizeQueueMap.get(chunk); | 
					
						
							| 
									
										
										
										
											2018-12-12 03:47:50 +08:00
										 |  |  | 						const { | 
					
						
							|  |  |  | 							minSize, | 
					
						
							|  |  |  | 							maxAsyncSize, | 
					
						
							|  |  |  | 							maxInitialSize, | 
					
						
							|  |  |  | 							automaticNameDelimiter | 
					
						
							| 
									
										
										
										
											2021-11-02 20:23:09 +08:00
										 |  |  | 						} = chunkConfig || fallbackCacheGroup; | 
					
						
							|  |  |  | 						if (!chunkConfig && !fallbackCacheGroup.chunksFilter(chunk)) | 
					
						
							|  |  |  | 							continue; | 
					
						
							| 
									
										
										
										
											2018-12-12 03:47:50 +08:00
										 |  |  | 						/** @type {SplitChunksSizes} */ | 
					
						
							|  |  |  | 						let maxSize; | 
					
						
							|  |  |  | 						if (chunk.isOnlyInitial()) { | 
					
						
							|  |  |  | 							maxSize = maxInitialSize; | 
					
						
							|  |  |  | 						} else if (chunk.canBeInitial()) { | 
					
						
							|  |  |  | 							maxSize = combineSizes(maxAsyncSize, maxInitialSize, Math.min); | 
					
						
							|  |  |  | 						} else { | 
					
						
							|  |  |  | 							maxSize = maxAsyncSize; | 
					
						
							|  |  |  | 						} | 
					
						
							|  |  |  | 						if (Object.keys(maxSize).length === 0) { | 
					
						
							|  |  |  | 							continue; | 
					
						
							|  |  |  | 						} | 
					
						
							| 
									
										
										
										
											2018-12-04 23:40:06 +08:00
										 |  |  | 						for (const key of Object.keys(maxSize)) { | 
					
						
							|  |  |  | 							const maxSizeValue = maxSize[key]; | 
					
						
							|  |  |  | 							const minSizeValue = minSize[key]; | 
					
						
							|  |  |  | 							if ( | 
					
						
							|  |  |  | 								typeof minSizeValue === "number" && | 
					
						
							|  |  |  | 								minSizeValue > maxSizeValue | 
					
						
							|  |  |  | 							) { | 
					
						
							|  |  |  | 								const keys = chunkConfig && chunkConfig.keys; | 
					
						
							| 
									
										
										
										
											2020-03-29 06:10:15 +08:00
										 |  |  | 								const warningKey = `${ | 
					
						
							|  |  |  | 									keys && keys.join() | 
					
						
							|  |  |  | 								} ${minSizeValue} ${maxSizeValue}`;
 | 
					
						
							| 
									
										
										
										
											2018-12-04 23:40:06 +08:00
										 |  |  | 								if (!incorrectMinMaxSizeSet.has(warningKey)) { | 
					
						
							|  |  |  | 									incorrectMinMaxSizeSet.add(warningKey); | 
					
						
							|  |  |  | 									compilation.warnings.push( | 
					
						
							|  |  |  | 										new MinMaxSizeWarning(keys, minSizeValue, maxSizeValue) | 
					
						
							|  |  |  | 									); | 
					
						
							|  |  |  | 								} | 
					
						
							| 
									
										
										
										
											2018-12-03 18:56:38 +08:00
										 |  |  | 							} | 
					
						
							|  |  |  | 						} | 
					
						
							| 
									
										
										
										
											2018-07-04 15:59:22 +08:00
										 |  |  | 						const results = deterministicGroupingForModules({ | 
					
						
							| 
									
										
										
										
											2018-12-11 04:19:10 +08:00
										 |  |  | 							minSize, | 
					
						
							| 
									
										
										
										
											2020-01-20 21:41:39 +08:00
										 |  |  | 							maxSize: mapObject(maxSize, (value, key) => { | 
					
						
							| 
									
										
										
										
											2018-12-04 23:40:06 +08:00
										 |  |  | 								const minSizeValue = minSize[key]; | 
					
						
							| 
									
										
										
										
											2020-01-20 21:41:39 +08:00
										 |  |  | 								return typeof minSizeValue === "number" | 
					
						
							|  |  |  | 									? Math.max(value, minSizeValue) | 
					
						
							|  |  |  | 									: value; | 
					
						
							|  |  |  | 							}), | 
					
						
							| 
									
										
										
										
											2018-08-14 17:18:22 +08:00
										 |  |  | 							items: chunkGraph.getChunkModulesIterable(chunk), | 
					
						
							| 
									
										
										
										
											2018-07-04 15:59:22 +08:00
										 |  |  | 							getKey(module) { | 
					
						
							| 
									
										
										
										
											2020-01-31 19:18:55 +08:00
										 |  |  | 								const cache = getKeyCache.get(module); | 
					
						
							|  |  |  | 								if (cache !== undefined) return cache; | 
					
						
							| 
									
										
										
										
											2021-08-06 17:50:55 +08:00
										 |  |  | 								const ident = cachedMakePathsRelative(module.identifier()); | 
					
						
							| 
									
										
										
										
											2018-12-04 23:40:06 +08:00
										 |  |  | 								const nameForCondition = | 
					
						
							|  |  |  | 									module.nameForCondition && module.nameForCondition(); | 
					
						
							|  |  |  | 								const name = nameForCondition | 
					
						
							| 
									
										
										
										
											2021-08-06 17:50:55 +08:00
										 |  |  | 									? cachedMakePathsRelative(nameForCondition) | 
					
						
							| 
									
										
										
										
											2018-07-04 15:59:22 +08:00
										 |  |  | 									: ident.replace(/^.*!|\?[^?!]*$/g, ""); | 
					
						
							|  |  |  | 								const fullKey = | 
					
						
							| 
									
										
										
										
											2020-02-04 16:18:54 +08:00
										 |  |  | 									name + | 
					
						
							|  |  |  | 									automaticNameDelimiter + | 
					
						
							|  |  |  | 									hashFilename(ident, outputOptions); | 
					
						
							| 
									
										
										
										
											2020-01-31 19:18:55 +08:00
										 |  |  | 								const key = requestToId(fullKey); | 
					
						
							|  |  |  | 								getKeyCache.set(module, key); | 
					
						
							|  |  |  | 								return key; | 
					
						
							| 
									
										
										
										
											2018-07-04 15:59:22 +08:00
										 |  |  | 							}, | 
					
						
							|  |  |  | 							getSize(module) { | 
					
						
							| 
									
										
										
										
											2018-12-04 23:40:06 +08:00
										 |  |  | 								const size = Object.create(null); | 
					
						
							| 
									
										
										
										
											2018-12-11 04:19:10 +08:00
										 |  |  | 								for (const key of module.getSourceTypes()) { | 
					
						
							| 
									
										
										
										
											2018-12-04 23:40:06 +08:00
										 |  |  | 									size[key] = module.size(key); | 
					
						
							| 
									
										
										
										
											2018-12-11 04:19:10 +08:00
										 |  |  | 								} | 
					
						
							| 
									
										
										
										
											2018-12-04 23:40:06 +08:00
										 |  |  | 								return size; | 
					
						
							| 
									
										
										
										
											2018-07-04 15:59:22 +08:00
										 |  |  | 							} | 
					
						
							|  |  |  | 						}); | 
					
						
							| 
									
										
										
										
											2020-06-16 22:40:55 +08:00
										 |  |  | 						if (results.length <= 1) { | 
					
						
							| 
									
										
										
										
											2018-12-11 04:19:10 +08:00
										 |  |  | 							continue; | 
					
						
							|  |  |  | 						} | 
					
						
							| 
									
										
										
										
											2018-07-04 15:59:22 +08:00
										 |  |  | 						for (let i = 0; i < results.length; i++) { | 
					
						
							|  |  |  | 							const group = results[i]; | 
					
						
							|  |  |  | 							const key = this.options.hidePathInfo | 
					
						
							| 
									
										
										
										
											2020-02-04 16:18:54 +08:00
										 |  |  | 								? hashFilename(group.key, outputOptions) | 
					
						
							| 
									
										
										
										
											2018-07-04 15:59:22 +08:00
										 |  |  | 								: group.key; | 
					
						
							|  |  |  | 							let name = chunk.name | 
					
						
							|  |  |  | 								? chunk.name + automaticNameDelimiter + key | 
					
						
							|  |  |  | 								: null; | 
					
						
							|  |  |  | 							if (name && name.length > 100) { | 
					
						
							|  |  |  | 								name = | 
					
						
							|  |  |  | 									name.slice(0, 100) + | 
					
						
							|  |  |  | 									automaticNameDelimiter + | 
					
						
							| 
									
										
										
										
											2020-02-04 16:18:54 +08:00
										 |  |  | 									hashFilename(name, outputOptions); | 
					
						
							| 
									
										
										
										
											2018-07-04 15:59:22 +08:00
										 |  |  | 							} | 
					
						
							|  |  |  | 							if (i !== results.length - 1) { | 
					
						
							| 
									
										
										
										
											2018-12-12 17:46:44 +08:00
										 |  |  | 								const newPart = compilation.addChunk(name); | 
					
						
							| 
									
										
										
										
											2018-07-04 15:59:22 +08:00
										 |  |  | 								chunk.split(newPart); | 
					
						
							| 
									
										
										
										
											2018-07-10 16:24:22 +08:00
										 |  |  | 								newPart.chunkReason = chunk.chunkReason; | 
					
						
							| 
									
										
										
										
											2018-07-04 15:59:22 +08:00
										 |  |  | 								// Add all modules to the new chunk
 | 
					
						
							|  |  |  | 								for (const module of group.items) { | 
					
						
							| 
									
										
										
										
											2018-12-11 04:19:10 +08:00
										 |  |  | 									if (!module.chunkCondition(newPart, compilation)) { | 
					
						
							|  |  |  | 										continue; | 
					
						
							|  |  |  | 									} | 
					
						
							| 
									
										
										
										
											2018-07-04 15:59:22 +08:00
										 |  |  | 									// Add module to new chunk
 | 
					
						
							| 
									
										
										
										
											2018-08-14 17:18:22 +08:00
										 |  |  | 									chunkGraph.connectChunkAndModule(newPart, module); | 
					
						
							| 
									
										
										
										
											2018-07-04 15:59:22 +08:00
										 |  |  | 									// Remove module from used chunks
 | 
					
						
							| 
									
										
										
										
											2018-08-14 17:18:22 +08:00
										 |  |  | 									chunkGraph.disconnectChunkAndModule(chunk, module); | 
					
						
							| 
									
										
										
										
											2018-07-04 15:59:22 +08:00
										 |  |  | 								} | 
					
						
							|  |  |  | 							} else { | 
					
						
							|  |  |  | 								// change the chunk to be a part
 | 
					
						
							|  |  |  | 								chunk.name = name; | 
					
						
							|  |  |  | 							} | 
					
						
							|  |  |  | 						} | 
					
						
							|  |  |  | 					} | 
					
						
							| 
									
										
										
										
											2019-07-25 21:46:08 +08:00
										 |  |  | 					logger.timeEnd("maxSize"); | 
					
						
							| 
									
										
										
										
											2018-01-20 00:06:59 +08:00
										 |  |  | 				} | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 			); | 
					
						
							| 
									
										
										
										
											2018-01-20 00:06:59 +08:00
										 |  |  | 		}); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | }; |