| 
									
										
										
										
											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
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											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(); | 
					
						
							| 
									
										
										
										
											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-05-29 20:50:40 +08:00
										 |  |  | 									for (const m of chunk.modulesIterable) { | 
					
						
							| 
									
										
										
										
											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 ( | 
					
						
							|  |  |  | 										!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-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-01-20 00:06:59 +08:00
										 |  |  | 					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) { | 
					
						
							| 
									
										
										
										
											2018-05-29 20:50:40 +08:00
										 |  |  | 						for (const m of chunk.modulesIterable) { | 
					
						
							|  |  |  | 							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) { | 
					
						
							|  |  |  | 							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) { | 
					
						
							| 
									
										
										
										
											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 | 
					
						
							|  |  |  | 			); | 
					
						
							| 
									
										
										
										
											2013-01-31 01:49:25 +08:00
										 |  |  | 		}); | 
					
						
							| 
									
										
										
										
											2017-01-05 02:44:01 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | module.exports = RemoveParentModulesPlugin; |