You cannot select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
	
	
		
			101 lines
		
	
	
		
			2.5 KiB
		
	
	
	
		
			JavaScript
		
	
		
		
			
		
	
	
			101 lines
		
	
	
		
			2.5 KiB
		
	
	
	
		
			JavaScript
		
	
| 
											9 months ago
										 | /* | ||
|  | 	MIT License http://www.opensource.org/licenses/mit-license.php
 | ||
|  | 	Author Tobias Koppers @sokra | ||
|  | */ | ||
|  | 
 | ||
|  | "use strict"; | ||
|  | 
 | ||
|  | const { STAGE_ADVANCED } = require("../OptimizationStages"); | ||
|  | 
 | ||
|  | /** @typedef {import("../Chunk")} Chunk */ | ||
|  | /** @typedef {import("../Compiler")} Compiler */ | ||
|  | 
 | ||
|  | /** | ||
|  |  * @typedef {Object} AggressiveMergingPluginOptions | ||
|  |  * @property {number=} minSizeReduce minimal size reduction to trigger merging | ||
|  |  */ | ||
|  | 
 | ||
|  | class AggressiveMergingPlugin { | ||
|  | 	/** | ||
|  | 	 * @param {AggressiveMergingPluginOptions=} [options] options object | ||
|  | 	 */ | ||
|  | 	constructor(options) { | ||
|  | 		if ( | ||
|  | 			(options !== undefined && typeof options !== "object") || | ||
|  | 			Array.isArray(options) | ||
|  | 		) { | ||
|  | 			throw new Error( | ||
|  | 				"Argument should be an options object. To use defaults, pass in nothing.\nFor more info on options, see https://webpack.js.org/plugins/" | ||
|  | 			); | ||
|  | 		} | ||
|  | 		this.options = options || {}; | ||
|  | 	} | ||
|  | 
 | ||
|  | 	/** | ||
|  | 	 * Apply the plugin | ||
|  | 	 * @param {Compiler} compiler the compiler instance | ||
|  | 	 * @returns {void} | ||
|  | 	 */ | ||
|  | 	apply(compiler) { | ||
|  | 		const options = this.options; | ||
|  | 		const minSizeReduce = options.minSizeReduce || 1.5; | ||
|  | 
 | ||
|  | 		compiler.hooks.thisCompilation.tap( | ||
|  | 			"AggressiveMergingPlugin", | ||
|  | 			compilation => { | ||
|  | 				compilation.hooks.optimizeChunks.tap( | ||
|  | 					{ | ||
|  | 						name: "AggressiveMergingPlugin", | ||
|  | 						stage: STAGE_ADVANCED | ||
|  | 					}, | ||
|  | 					chunks => { | ||
|  | 						const chunkGraph = compilation.chunkGraph; | ||
|  | 						/** @type {{a: Chunk, b: Chunk, improvement: number}[]} */ | ||
|  | 						let combinations = []; | ||
|  | 						for (const a of chunks) { | ||
|  | 							if (a.canBeInitial()) continue; | ||
|  | 							for (const b of chunks) { | ||
|  | 								if (b.canBeInitial()) continue; | ||
|  | 								if (b === a) break; | ||
|  | 								if (!chunkGraph.canChunksBeIntegrated(a, b)) { | ||
|  | 									continue; | ||
|  | 								} | ||
|  | 								const aSize = chunkGraph.getChunkSize(b, { | ||
|  | 									chunkOverhead: 0 | ||
|  | 								}); | ||
|  | 								const bSize = chunkGraph.getChunkSize(a, { | ||
|  | 									chunkOverhead: 0 | ||
|  | 								}); | ||
|  | 								const abSize = chunkGraph.getIntegratedChunksSize(b, a, { | ||
|  | 									chunkOverhead: 0 | ||
|  | 								}); | ||
|  | 								const improvement = (aSize + bSize) / abSize; | ||
|  | 								combinations.push({ | ||
|  | 									a, | ||
|  | 									b, | ||
|  | 									improvement | ||
|  | 								}); | ||
|  | 							} | ||
|  | 						} | ||
|  | 
 | ||
|  | 						combinations.sort((a, b) => { | ||
|  | 							return b.improvement - a.improvement; | ||
|  | 						}); | ||
|  | 
 | ||
|  | 						const pair = combinations[0]; | ||
|  | 
 | ||
|  | 						if (!pair) return; | ||
|  | 						if (pair.improvement < minSizeReduce) return; | ||
|  | 
 | ||
|  | 						chunkGraph.integrateChunks(pair.b, pair.a); | ||
|  | 						compilation.chunks.delete(pair.a); | ||
|  | 						return true; | ||
|  | 					} | ||
|  | 				); | ||
|  | 			} | ||
|  | 		); | ||
|  | 	} | ||
|  | } | ||
|  | 
 | ||
|  | module.exports = AggressiveMergingPlugin; |