| 
									
										
										
										
											2013-02-11 17:52:19 +08:00
										 |  |  | /* | 
					
						
							|  |  |  | 	MIT License http://www.opensource.org/licenses/mit-license.php
 | 
					
						
							|  |  |  | 	Author Tobias Koppers @sokra | 
					
						
							|  |  |  | */ | 
					
						
							| 
									
										
										
										
											2018-07-30 23:08:51 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-05 13:42:36 +08:00
										 |  |  | "use strict"; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-31 04:30:27 +08:00
										 |  |  | const { STAGE_ADVANCED } = require("../OptimizationStages"); | 
					
						
							| 
									
										
										
										
											2021-04-16 21:35:18 +08:00
										 |  |  | const createSchemaValidation = require("../util/create-schema-validation"); | 
					
						
							| 
									
										
										
										
											2017-10-28 05:23:38 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-04-16 21:35:18 +08:00
										 |  |  | /** @typedef {import("../../declarations/plugins/optimize/MinChunkSizePlugin").MinChunkSizePluginOptions} MinChunkSizePluginOptions */ | 
					
						
							| 
									
										
										
										
											2018-08-14 17:18:22 +08:00
										 |  |  | /** @typedef {import("../Chunk")} Chunk */ | 
					
						
							|  |  |  | /** @typedef {import("../Compiler")} Compiler */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-04-16 21:35:18 +08:00
										 |  |  | const validate = createSchemaValidation( | 
					
						
							|  |  |  | 	require("../../schemas/plugins/optimize/MinChunkSizePlugin.check.js"), | 
					
						
							|  |  |  | 	() => require("../../schemas/plugins/optimize/MinChunkSizePlugin.json"), | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		name: "Min Chunk Size Plugin", | 
					
						
							|  |  |  | 		baseDataPath: "options" | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | ); | 
					
						
							| 
									
										
										
										
											2018-09-20 16:13:55 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-05 13:42:36 +08:00
										 |  |  | class MinChunkSizePlugin { | 
					
						
							| 
									
										
										
										
											2018-09-20 16:13:55 +08:00
										 |  |  | 	/** | 
					
						
							|  |  |  | 	 * @param {MinChunkSizePluginOptions} options options object | 
					
						
							|  |  |  | 	 */ | 
					
						
							| 
									
										
										
										
											2017-01-05 13:42:36 +08:00
										 |  |  | 	constructor(options) { | 
					
						
							| 
									
										
										
										
											2021-04-16 21:35:18 +08:00
										 |  |  | 		validate(options); | 
					
						
							| 
									
										
										
										
											2017-01-05 13:42:36 +08:00
										 |  |  | 		this.options = options; | 
					
						
							| 
									
										
										
										
											2015-05-28 00:46:47 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2013-02-11 17:52:19 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-08-14 17:18:22 +08:00
										 |  |  | 	/** | 
					
						
							| 
									
										
										
										
											2020-04-23 16:48:36 +08:00
										 |  |  | 	 * Apply the plugin | 
					
						
							|  |  |  | 	 * @param {Compiler} compiler the compiler instance | 
					
						
							| 
									
										
										
										
											2018-08-14 17:18:22 +08:00
										 |  |  | 	 * @returns {void} | 
					
						
							|  |  |  | 	 */ | 
					
						
							| 
									
										
										
										
											2017-01-05 13:42:36 +08:00
										 |  |  | 	apply(compiler) { | 
					
						
							|  |  |  | 		const options = this.options; | 
					
						
							|  |  |  | 		const minChunkSize = options.minChunkSize; | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 		compiler.hooks.compilation.tap("MinChunkSizePlugin", compilation => { | 
					
						
							| 
									
										
										
										
											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: "MinChunkSizePlugin", | 
					
						
							|  |  |  | 					stage: STAGE_ADVANCED | 
					
						
							| 
									
										
										
										
											2018-12-09 19:54:17 +08:00
										 |  |  | 				}, | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 				chunks => { | 
					
						
							| 
									
										
										
										
											2018-08-14 17:18:22 +08:00
										 |  |  | 					const chunkGraph = compilation.chunkGraph; | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 					const equalOptions = { | 
					
						
							|  |  |  | 						chunkOverhead: 1, | 
					
						
							|  |  |  | 						entryChunkMultiplicator: 1 | 
					
						
							|  |  |  | 					}; | 
					
						
							| 
									
										
										
										
											2013-06-18 00:55:11 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-20 21:41:39 +08:00
										 |  |  | 					const chunkSizesMap = new Map(); | 
					
						
							|  |  |  | 					/** @type {[Chunk, Chunk][]} */ | 
					
						
							|  |  |  | 					const combinations = []; | 
					
						
							|  |  |  | 					/** @type {Chunk[]} */ | 
					
						
							|  |  |  | 					const smallChunks = []; | 
					
						
							|  |  |  | 					const visitedChunks = []; | 
					
						
							|  |  |  | 					for (const a of chunks) { | 
					
						
							|  |  |  | 						// check if one of the chunks sizes is smaller than the minChunkSize
 | 
					
						
							|  |  |  | 						// and filter pairs that can NOT be integrated!
 | 
					
						
							|  |  |  | 						if (chunkGraph.getChunkSize(a, equalOptions) < minChunkSize) { | 
					
						
							|  |  |  | 							smallChunks.push(a); | 
					
						
							|  |  |  | 							for (const b of visitedChunks) { | 
					
						
							|  |  |  | 								if (chunkGraph.canChunksBeIntegrated(b, a)) | 
					
						
							|  |  |  | 									combinations.push([b, a]); | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 							} | 
					
						
							| 
									
										
										
										
											2020-01-20 21:41:39 +08:00
										 |  |  | 						} else { | 
					
						
							|  |  |  | 							for (const b of smallChunks) { | 
					
						
							|  |  |  | 								if (chunkGraph.canChunksBeIntegrated(b, a)) | 
					
						
							|  |  |  | 									combinations.push([b, a]); | 
					
						
							|  |  |  | 							} | 
					
						
							|  |  |  | 						} | 
					
						
							|  |  |  | 						chunkSizesMap.set(a, chunkGraph.getChunkSize(a, options)); | 
					
						
							|  |  |  | 						visitedChunks.push(a); | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					const sortedSizeFilteredExtendedPairCombinations = combinations | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 						.map(pair => { | 
					
						
							|  |  |  | 							// extend combination pairs with size and integrated size
 | 
					
						
							| 
									
										
										
										
											2020-01-20 21:41:39 +08:00
										 |  |  | 							const a = chunkSizesMap.get(pair[0]); | 
					
						
							|  |  |  | 							const b = chunkSizesMap.get(pair[1]); | 
					
						
							| 
									
										
										
										
											2018-08-14 17:18:22 +08:00
										 |  |  | 							const ab = chunkGraph.getIntegratedChunksSize( | 
					
						
							|  |  |  | 								pair[0], | 
					
						
							|  |  |  | 								pair[1], | 
					
						
							|  |  |  | 								options | 
					
						
							|  |  |  | 							); | 
					
						
							|  |  |  | 							/** @type {[number, number, Chunk, Chunk]} */ | 
					
						
							|  |  |  | 							const extendedPair = [a + b - ab, ab, pair[0], pair[1]]; | 
					
						
							|  |  |  | 							return extendedPair; | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 						}) | 
					
						
							|  |  |  | 						.sort((a, b) => { | 
					
						
							| 
									
										
										
										
											2020-03-13 00:51:26 +08:00
										 |  |  | 							// sadly javascript does an in place sort here
 | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 							// sort by size
 | 
					
						
							|  |  |  | 							const diff = b[0] - a[0]; | 
					
						
							|  |  |  | 							if (diff !== 0) return diff; | 
					
						
							|  |  |  | 							return a[1] - b[1]; | 
					
						
							|  |  |  | 						}); | 
					
						
							| 
									
										
										
										
											2013-06-18 00:55:11 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 					if (sortedSizeFilteredExtendedPairCombinations.length === 0) return; | 
					
						
							| 
									
										
										
										
											2017-02-05 09:19:58 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 					const pair = sortedSizeFilteredExtendedPairCombinations[0]; | 
					
						
							| 
									
										
										
										
											2013-06-18 00:55:11 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-08-14 17:18:22 +08:00
										 |  |  | 					chunkGraph.integrateChunks(pair[2], pair[3]); | 
					
						
							| 
									
										
										
										
											2018-09-06 22:59:11 +08:00
										 |  |  | 					compilation.chunks.delete(pair[3]); | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 					return true; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			); | 
					
						
							| 
									
										
										
										
											2013-02-11 17:52:19 +08:00
										 |  |  | 		}); | 
					
						
							| 
									
										
										
										
											2017-01-05 13:42:36 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | module.exports = MinChunkSizePlugin; |