| 
									
										
										
										
											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 02:44:01 +08:00
										 |  |  | "use strict"; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-31 04:30:27 +08:00
										 |  |  | const { STAGE_BASIC } = require("../OptimizationStages"); | 
					
						
							| 
									
										
										
										
											2017-11-25 00:23:33 +08:00
										 |  |  | const Queue = require("../util/Queue"); | 
					
						
							| 
									
										
										
										
											2018-03-22 19:05:58 +08:00
										 |  |  | const { intersect } = require("../util/SetHelpers"); | 
					
						
							| 
									
										
										
										
											2017-11-25 00:23:33 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-08-14 17:18:22 +08:00
										 |  |  | /** @typedef {import("../Compiler")} Compiler */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-05 02:44:01 +08:00
										 |  |  | class RemoveParentModulesPlugin { | 
					
						
							| 
									
										
										
										
											2018-08-14 17:18:22 +08:00
										 |  |  | 	/** | 
					
						
							|  |  |  | 	 * @param {Compiler} compiler the compiler | 
					
						
							|  |  |  | 	 * @returns {void} | 
					
						
							|  |  |  | 	 */ | 
					
						
							| 
									
										
										
										
											2017-01-05 02:44:01 +08:00
										 |  |  | 	apply(compiler) { | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 		compiler.hooks.compilation.tap("RemoveParentModulesPlugin", compilation => { | 
					
						
							| 
									
										
										
										
											2018-01-20 00:06:59 +08:00
										 |  |  | 			const handler = (chunks, chunkGroups) => { | 
					
						
							| 
									
										
										
										
											2018-08-14 17:18:22 +08:00
										 |  |  | 				const chunkGraph = compilation.chunkGraph; | 
					
						
							| 
									
										
										
										
											2018-01-10 05:39:16 +08:00
										 |  |  | 				const queue = new Queue(); | 
					
						
							| 
									
										
										
										
											2018-04-27 20:23:48 +08:00
										 |  |  | 				const availableModulesMap = new WeakMap(); | 
					
						
							| 
									
										
										
										
											2017-01-24 02:52:47 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 				for (const chunkGroup of compilation.entrypoints.values()) { | 
					
						
							| 
									
										
										
										
											2017-11-25 00:23:33 +08:00
										 |  |  | 					// initialize available modules for chunks without parents
 | 
					
						
							| 
									
										
										
										
											2018-01-20 00:06:59 +08:00
										 |  |  | 					availableModulesMap.set(chunkGroup, new Set()); | 
					
						
							| 
									
										
										
										
											2018-05-29 20:50:40 +08:00
										 |  |  | 					for (const child of chunkGroup.childrenIterable) { | 
					
						
							|  |  |  | 						queue.enqueue(child); | 
					
						
							|  |  |  | 					} | 
					
						
							| 
									
										
										
										
											2017-11-25 00:23:33 +08:00
										 |  |  | 				} | 
					
						
							| 
									
										
										
										
											2017-01-24 02:52:47 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 				while (queue.length > 0) { | 
					
						
							| 
									
										
										
										
											2018-01-20 00:06:59 +08:00
										 |  |  | 					const chunkGroup = queue.dequeue(); | 
					
						
							|  |  |  | 					let availableModules = availableModulesMap.get(chunkGroup); | 
					
						
							| 
									
										
										
										
											2017-11-25 00:23:33 +08:00
										 |  |  | 					let changed = false; | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 					for (const parent of chunkGroup.parentsIterable) { | 
					
						
							| 
									
										
										
										
											2018-01-20 00:06:59 +08:00
										 |  |  | 						const availableModulesInParent = availableModulesMap.get(parent); | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 						if (availableModulesInParent !== undefined) { | 
					
						
							| 
									
										
										
										
											2018-01-20 00:06:59 +08:00
										 |  |  | 							// If we know the available modules in parent: process these
 | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 							if (availableModules === undefined) { | 
					
						
							| 
									
										
										
										
											2018-01-20 00:06:59 +08:00
										 |  |  | 								// if we have not own info yet: create new entry
 | 
					
						
							|  |  |  | 								availableModules = new Set(availableModulesInParent); | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 								for (const chunk of parent.chunks) { | 
					
						
							| 
									
										
										
										
											2018-08-14 17:18:22 +08:00
										 |  |  | 									for (const m of chunkGraph.getChunkModulesIterable(chunk)) { | 
					
						
							| 
									
										
										
										
											2018-01-20 00:06:59 +08:00
										 |  |  | 										availableModules.add(m); | 
					
						
							| 
									
										
										
										
											2018-05-29 20:50:40 +08:00
										 |  |  | 									} | 
					
						
							| 
									
										
										
										
											2018-01-10 05:39:16 +08:00
										 |  |  | 								} | 
					
						
							| 
									
										
										
										
											2018-01-20 00:06:59 +08:00
										 |  |  | 								availableModulesMap.set(chunkGroup, availableModules); | 
					
						
							|  |  |  | 								changed = true; | 
					
						
							|  |  |  | 							} else { | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 								for (const m of availableModules) { | 
					
						
							|  |  |  | 									if ( | 
					
						
							| 
									
										
										
										
											2018-08-14 17:18:22 +08:00
										 |  |  | 										!chunkGraph.isModuleInChunkGroup(m, parent) && | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 										!availableModulesInParent.has(m) | 
					
						
							|  |  |  | 									) { | 
					
						
							| 
									
										
										
										
											2018-01-20 00:06:59 +08:00
										 |  |  | 										availableModules.delete(m); | 
					
						
							|  |  |  | 										changed = true; | 
					
						
							| 
									
										
										
										
											2017-11-25 00:23:33 +08:00
										 |  |  | 									} | 
					
						
							|  |  |  | 								} | 
					
						
							|  |  |  | 							} | 
					
						
							| 
									
										
										
										
											2017-01-05 02:44:01 +08:00
										 |  |  | 						} | 
					
						
							| 
									
										
										
										
											2017-01-24 02:52:47 +08:00
										 |  |  | 					} | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 					if (changed) { | 
					
						
							| 
									
										
										
										
											2017-11-25 00:23:33 +08:00
										 |  |  | 						// if something changed: enqueue our children
 | 
					
						
							| 
									
										
										
										
											2018-05-29 20:50:40 +08:00
										 |  |  | 						for (const child of chunkGroup.childrenIterable) { | 
					
						
							| 
									
										
										
										
											2017-11-25 00:23:33 +08:00
										 |  |  | 							queue.enqueue(child); | 
					
						
							| 
									
										
										
										
											2018-05-29 20:50:40 +08:00
										 |  |  | 						} | 
					
						
							| 
									
										
										
										
											2017-11-25 00:23:33 +08:00
										 |  |  | 					} | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				// now we have available modules for every chunk
 | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 				for (const chunk of chunks) { | 
					
						
							|  |  |  | 					const availableModulesSets = Array.from( | 
					
						
							|  |  |  | 						chunk.groupsIterable, | 
					
						
							|  |  |  | 						chunkGroup => availableModulesMap.get(chunkGroup) | 
					
						
							|  |  |  | 					); | 
					
						
							|  |  |  | 					if (availableModulesSets.some(s => s === undefined)) continue; // No info about this chunk group
 | 
					
						
							| 
									
										
										
										
											2018-04-27 20:23:48 +08:00
										 |  |  | 					const availableModules = | 
					
						
							|  |  |  | 						availableModulesSets.length === 1 | 
					
						
							|  |  |  | 							? availableModulesSets[0] | 
					
						
							|  |  |  | 							: intersect(availableModulesSets); | 
					
						
							| 
									
										
										
										
											2018-08-14 17:18:22 +08:00
										 |  |  | 					const numberOfModules = chunkGraph.getNumberOfChunkModules(chunk); | 
					
						
							| 
									
										
										
										
											2017-11-25 00:23:33 +08:00
										 |  |  | 					const toRemove = new Set(); | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 					if (numberOfModules < availableModules.size) { | 
					
						
							| 
									
										
										
										
											2018-08-14 17:18:22 +08:00
										 |  |  | 						for (const m of chunkGraph.getChunkModulesIterable(chunk)) { | 
					
						
							| 
									
										
										
										
											2018-05-29 20:50:40 +08:00
										 |  |  | 							if (availableModules.has(m)) { | 
					
						
							|  |  |  | 								toRemove.add(m); | 
					
						
							|  |  |  | 							} | 
					
						
							|  |  |  | 						} | 
					
						
							| 
									
										
										
										
											2017-11-25 00:23:33 +08:00
										 |  |  | 					} else { | 
					
						
							| 
									
										
										
										
											2018-05-29 20:50:40 +08:00
										 |  |  | 						for (const m of availableModules) { | 
					
						
							| 
									
										
										
										
											2018-08-14 17:18:22 +08:00
										 |  |  | 							if (chunkGraph.isModuleInChunk(m, chunk)) { | 
					
						
							| 
									
										
										
										
											2018-05-29 20:50:40 +08:00
										 |  |  | 								toRemove.add(m); | 
					
						
							|  |  |  | 							} | 
					
						
							|  |  |  | 						} | 
					
						
							| 
									
										
										
										
											2017-11-25 00:23:33 +08:00
										 |  |  | 					} | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 					for (const module of toRemove) { | 
					
						
							| 
									
										
										
										
											2018-08-14 17:18:22 +08:00
										 |  |  | 						chunkGraph.disconnectChunkAndModule(chunk, module); | 
					
						
							| 
									
										
										
										
											2017-11-25 00:23:33 +08:00
										 |  |  | 					} | 
					
						
							| 
									
										
										
										
											2017-01-24 02:52:47 +08:00
										 |  |  | 				} | 
					
						
							| 
									
										
										
										
											2017-12-14 04:35:39 +08:00
										 |  |  | 			}; | 
					
						
							| 
									
										
										
										
											2018-07-31 04:30:27 +08:00
										 |  |  | 			compilation.hooks.optimizeChunks.tap( | 
					
						
							|  |  |  | 				/** @type {TODO} */ ({ | 
					
						
							|  |  |  | 					name: "RemoveParentModulesPlugin", | 
					
						
							|  |  |  | 					stage: STAGE_BASIC | 
					
						
							|  |  |  | 				}), | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 				handler | 
					
						
							|  |  |  | 			); | 
					
						
							| 
									
										
										
										
											2013-01-31 01:49:25 +08:00
										 |  |  | 		}); | 
					
						
							| 
									
										
										
										
											2017-01-05 02:44:01 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | module.exports = RemoveParentModulesPlugin; |