| 
									
										
										
										
											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"; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-10-29 17:19:28 +08:00
										 |  |  | const validateOptions = require("schema-utils"); | 
					
						
							| 
									
										
										
										
											2017-11-11 20:05:55 +08:00
										 |  |  | const schema = require("../../schemas/plugins/optimize/MinChunkSizePlugin.json"); | 
					
						
							| 
									
										
										
										
											2018-07-31 04:30:27 +08:00
										 |  |  | const { STAGE_ADVANCED } = require("../OptimizationStages"); | 
					
						
							| 
									
										
										
										
											2017-10-28 05:23:38 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-08-14 17:18:22 +08:00
										 |  |  | /** @typedef {import("../Chunk")} Chunk */ | 
					
						
							|  |  |  | /** @typedef {import("../Compiler")} Compiler */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-20 16:13:55 +08:00
										 |  |  | /** @typedef {import("../../declarations/plugins/optimize/MinChunkSizePlugin").MinChunkSizePluginOptions} MinChunkSizePluginOptions */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											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) { | 
					
						
							| 
									
										
										
										
											2019-08-07 21:55:03 +08:00
										 |  |  | 		validateOptions(schema, options, { | 
					
						
							|  |  |  | 			name: "Min Chunk Size Plugin", | 
					
						
							|  |  |  | 			baseDataPath: "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
										 |  |  | 	/** | 
					
						
							|  |  |  | 	 * @param {Compiler} compiler webpack compiler | 
					
						
							|  |  |  | 	 * @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
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-06 22:59:11 +08:00
										 |  |  | 					const sortedSizeFilteredExtendedPairCombinations = Array.from(chunks) | 
					
						
							| 
									
										
										
										
											2018-08-14 17:18:22 +08:00
										 |  |  | 						.reduce((/** @type {[Chunk, Chunk][]} */ combinations, a, idx) => { | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 							// create combination pairs
 | 
					
						
							| 
									
										
										
										
											2018-09-06 22:59:11 +08:00
										 |  |  | 							for (const b of chunks) { | 
					
						
							|  |  |  | 								if (b === a) break; | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 								combinations.push([b, a]); | 
					
						
							|  |  |  | 							} | 
					
						
							|  |  |  | 							return combinations; | 
					
						
							|  |  |  | 						}, []) | 
					
						
							|  |  |  | 						.filter(pair => { | 
					
						
							|  |  |  | 							// check if one of the chunks sizes is smaller than the minChunkSize
 | 
					
						
							|  |  |  | 							const p0SmallerThanMinChunkSize = | 
					
						
							| 
									
										
										
										
											2018-08-14 17:18:22 +08:00
										 |  |  | 								chunkGraph.getChunkSize(pair[0], equalOptions) < minChunkSize; | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 							const p1SmallerThanMinChunkSize = | 
					
						
							| 
									
										
										
										
											2018-08-14 17:18:22 +08:00
										 |  |  | 								chunkGraph.getChunkSize(pair[1], equalOptions) < minChunkSize; | 
					
						
							|  |  |  | 							if (!p0SmallerThanMinChunkSize && !p1SmallerThanMinChunkSize) | 
					
						
							|  |  |  | 								return false; | 
					
						
							|  |  |  | 							// filter pairs that can NOT be integrated!
 | 
					
						
							|  |  |  | 							return chunkGraph.canChunksBeIntegrated(pair[0], pair[1]); | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 						}) | 
					
						
							|  |  |  | 						.map(pair => { | 
					
						
							|  |  |  | 							// extend combination pairs with size and integrated size
 | 
					
						
							| 
									
										
										
										
											2018-08-14 17:18:22 +08:00
										 |  |  | 							const a = chunkGraph.getChunkSize(pair[0], options); | 
					
						
							|  |  |  | 							const b = chunkGraph.getChunkSize(pair[1], options); | 
					
						
							|  |  |  | 							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) => { | 
					
						
							|  |  |  | 							// sadly javascript does an inplace sort here
 | 
					
						
							|  |  |  | 							// 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; |