| 
									
										
										
										
											2013-01-31 01:49:25 +08:00
										 |  |  | /* | 
					
						
							|  |  |  | 	MIT License http://www.opensource.org/licenses/mit-license.php
 | 
					
						
							|  |  |  | 	Author Tobias Koppers @sokra | 
					
						
							|  |  |  | */ | 
					
						
							| 
									
										
										
										
											2017-01-05 02:44:01 +08:00
										 |  |  | "use strict"; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											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-01-06 04:01:00 +08:00
										 |  |  | const getParentChunksWithModule = (currentChunk, module) => { | 
					
						
							|  |  |  | 	const chunks = []; | 
					
						
							|  |  |  | 	const stack = new Set(currentChunk.parentsIterable); | 
					
						
							| 
									
										
										
										
											2017-01-26 03:39:24 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 	for (const chunk of stack) { | 
					
						
							|  |  |  | 		if (chunk.containsModule(module)) { | 
					
						
							| 
									
										
										
										
											2018-01-06 04:01:00 +08:00
										 |  |  | 			chunks.push(chunk); | 
					
						
							|  |  |  | 		} else { | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 			for (const parent of chunk.parentsIterable) { | 
					
						
							| 
									
										
										
										
											2018-01-06 04:01:00 +08:00
										 |  |  | 				stack.add(parent); | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2017-01-26 03:39:24 +08:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2016-04-11 05:38:41 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2018-01-06 04:01:00 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-11 05:38:41 +08:00
										 |  |  | 	return chunks; | 
					
						
							| 
									
										
										
										
											2017-11-08 18:32:05 +08:00
										 |  |  | }; | 
					
						
							| 
									
										
										
										
											2014-09-08 04:54:38 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-05 02:44:01 +08:00
										 |  |  | class RemoveParentModulesPlugin { | 
					
						
							|  |  |  | 	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-01-10 05:39:16 +08:00
										 |  |  | 				const queue = new Queue(); | 
					
						
							| 
									
										
										
										
											2017-11-25 00:23:33 +08:00
										 |  |  | 				const availableModulesMap = new Map(); | 
					
						
							| 
									
										
										
										
											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-02-25 09:00:20 +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) { | 
					
						
							|  |  |  | 									for (const m of chunk.modulesIterable) | 
					
						
							| 
									
										
										
										
											2018-01-20 00:06:59 +08:00
										 |  |  | 										availableModules.add(m); | 
					
						
							| 
									
										
										
										
											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 ( | 
					
						
							|  |  |  | 										!parent.containsModule(m) && | 
					
						
							|  |  |  | 										!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-02-25 09:00:20 +08:00
										 |  |  | 						for (const child of chunkGroup.childrenIterable) | 
					
						
							| 
									
										
										
										
											2017-11-25 00:23:33 +08:00
										 |  |  | 							queue.enqueue(child); | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				// 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-01-20 00:06:59 +08:00
										 |  |  | 					const availableModules = intersect(availableModulesSets); | 
					
						
							|  |  |  | 					const numberOfModules = chunk.getNumberOfModules(); | 
					
						
							| 
									
										
										
										
											2017-11-25 00:23:33 +08:00
										 |  |  | 					const toRemove = new Set(); | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 					if (numberOfModules < availableModules.size) { | 
					
						
							|  |  |  | 						for (const m of chunk.modulesIterable) | 
					
						
							|  |  |  | 							if (availableModules.has(m)) toRemove.add(m); | 
					
						
							| 
									
										
										
										
											2017-11-25 00:23:33 +08:00
										 |  |  | 					} else { | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 						for (const m of availableModules) | 
					
						
							|  |  |  | 							if (chunk.containsModule(m)) toRemove.add(m); | 
					
						
							| 
									
										
										
										
											2017-11-25 00:23:33 +08:00
										 |  |  | 					} | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 					for (const module of toRemove) { | 
					
						
							|  |  |  | 						module.rewriteChunkInReasons( | 
					
						
							|  |  |  | 							chunk, | 
					
						
							|  |  |  | 							getParentChunksWithModule(chunk, module) | 
					
						
							|  |  |  | 						); | 
					
						
							| 
									
										
										
										
											2017-11-25 00:23:33 +08:00
										 |  |  | 						chunk.removeModule(module); | 
					
						
							|  |  |  | 					} | 
					
						
							| 
									
										
										
										
											2017-01-24 02:52:47 +08:00
										 |  |  | 				} | 
					
						
							| 
									
										
										
										
											2017-12-14 04:35:39 +08:00
										 |  |  | 			}; | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 			compilation.hooks.optimizeChunksBasic.tap( | 
					
						
							|  |  |  | 				"RemoveParentModulesPlugin", | 
					
						
							|  |  |  | 				handler | 
					
						
							|  |  |  | 			); | 
					
						
							|  |  |  | 			compilation.hooks.optimizeExtractedChunksBasic.tap( | 
					
						
							|  |  |  | 				"RemoveParentModulesPlugin", | 
					
						
							|  |  |  | 				handler | 
					
						
							|  |  |  | 			); | 
					
						
							| 
									
										
										
										
											2013-01-31 01:49:25 +08:00
										 |  |  | 		}); | 
					
						
							| 
									
										
										
										
											2017-01-05 02:44:01 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | module.exports = RemoveParentModulesPlugin; |