| 
									
										
										
										
											2013-01-31 01:49:25 +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 12:17:12 +08:00
										 |  |  | "use strict"; | 
					
						
							| 
									
										
										
										
											2013-01-31 01:49:25 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											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/LimitChunkCountPlugin.json"); | 
					
						
							| 
									
										
										
										
											2018-07-31 04:30:27 +08:00
										 |  |  | const { STAGE_ADVANCED } = require("../OptimizationStages"); | 
					
						
							| 
									
										
										
										
											2018-10-17 23:14:50 +08:00
										 |  |  | const { compareChunks } = require("../util/comparators"); | 
					
						
							| 
									
										
										
										
											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/LimitChunkCountPlugin").LimitChunkCountPluginOptions} LimitChunkCountPluginOptions */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-05 12:17:12 +08:00
										 |  |  | class LimitChunkCountPlugin { | 
					
						
							| 
									
										
										
										
											2018-09-20 16:13:55 +08:00
										 |  |  | 	/** | 
					
						
							|  |  |  | 	 * @param {LimitChunkCountPluginOptions=} options options object | 
					
						
							|  |  |  | 	 */ | 
					
						
							| 
									
										
										
										
											2018-09-25 22:07:42 +08:00
										 |  |  | 	constructor(options = {}) { | 
					
						
							| 
									
										
										
										
											2018-09-20 16:13:55 +08:00
										 |  |  | 		validateOptions(schema, options, "Limit Chunk Count Plugin"); | 
					
						
							|  |  |  | 		this.options = options; | 
					
						
							| 
									
										
										
										
											2017-01-05 12:17:12 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2018-08-14 17:18:22 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	/** | 
					
						
							|  |  |  | 	 * @param {Compiler} compiler webpack compiler | 
					
						
							|  |  |  | 	 * @returns {void} | 
					
						
							|  |  |  | 	 */ | 
					
						
							| 
									
										
										
										
											2017-01-05 12:17:12 +08:00
										 |  |  | 	apply(compiler) { | 
					
						
							|  |  |  | 		const options = this.options; | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 		compiler.hooks.compilation.tap("LimitChunkCountPlugin", compilation => { | 
					
						
							| 
									
										
										
										
											2018-07-31 04:30:27 +08:00
										 |  |  | 			compilation.hooks.optimizeChunks.tap( | 
					
						
							|  |  |  | 				/** @type {TODO} */ ({ | 
					
						
							|  |  |  | 					name: "LimitChunkCountPlugin", | 
					
						
							|  |  |  | 					stage: STAGE_ADVANCED | 
					
						
							|  |  |  | 				}), | 
					
						
							| 
									
										
										
										
											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 maxChunks = options.maxChunks; | 
					
						
							|  |  |  | 					if (!maxChunks) return; | 
					
						
							|  |  |  | 					if (maxChunks < 1) return; | 
					
						
							| 
									
										
										
										
											2018-09-06 22:59:11 +08:00
										 |  |  | 					if (compilation.chunks.size <= maxChunks) return; | 
					
						
							| 
									
										
										
										
											2013-01-31 01:49:25 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-17 23:14:50 +08:00
										 |  |  | 					const compareChunksWithGraph = compareChunks(chunkGraph); | 
					
						
							|  |  |  | 					const orderedChunks = Array.from(chunks).sort(compareChunksWithGraph); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					const sortedExtendedPairCombinations = orderedChunks | 
					
						
							| 
									
										
										
										
											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-10-17 23:14:50 +08:00
										 |  |  | 							for (const b of orderedChunks) { | 
					
						
							| 
									
										
										
										
											2018-09-06 22:59:11 +08:00
										 |  |  | 								if (b === a) break; | 
					
						
							| 
									
										
										
										
											2018-08-14 17:18:22 +08:00
										 |  |  | 								// filter pairs that can NOT be integrated!
 | 
					
						
							|  |  |  | 								if (chunkGraph.canChunksBeIntegrated(b, a)) { | 
					
						
							|  |  |  | 									combinations.push([b, a]); | 
					
						
							|  |  |  | 								} | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 							} | 
					
						
							|  |  |  | 							return combinations; | 
					
						
							|  |  |  | 						}, []) | 
					
						
							|  |  |  | 						.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, number, number]} */ | 
					
						
							|  |  |  | 							const extendedPair = [a + b - ab, ab, pair[0], pair[1], a, b]; | 
					
						
							|  |  |  | 							return extendedPair; | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 						}) | 
					
						
							|  |  |  | 						.sort((a, b) => { | 
					
						
							|  |  |  | 							// sadly javascript does an inplace sort here
 | 
					
						
							|  |  |  | 							// sort them by size
 | 
					
						
							| 
									
										
										
										
											2018-10-17 23:14:50 +08:00
										 |  |  | 							const diff1 = b[0] - a[0]; | 
					
						
							|  |  |  | 							if (diff1 !== 0) return diff1; | 
					
						
							|  |  |  | 							const diff2 = a[1] - b[1]; | 
					
						
							|  |  |  | 							if (diff2 !== 0) return diff2; | 
					
						
							|  |  |  | 							const diff3 = compareChunksWithGraph(a[2], b[2]); | 
					
						
							|  |  |  | 							if (diff3 !== 0) return diff3; | 
					
						
							|  |  |  | 							return compareChunksWithGraph(a[3], b[3]); | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 						}); | 
					
						
							| 
									
										
										
										
											2013-01-31 01:49:25 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 					const pair = sortedExtendedPairCombinations[0]; | 
					
						
							| 
									
										
										
										
											2013-01-31 01:49:25 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-08-14 17:18:22 +08:00
										 |  |  | 					if (pair) { | 
					
						
							|  |  |  | 						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; | 
					
						
							|  |  |  | 					} | 
					
						
							| 
									
										
										
										
											2014-02-04 01:12:19 +08:00
										 |  |  | 				} | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 			); | 
					
						
							| 
									
										
										
										
											2013-01-31 01:49:25 +08:00
										 |  |  | 		}); | 
					
						
							| 
									
										
										
										
											2017-01-05 12:17:12 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | module.exports = LimitChunkCountPlugin; |