| 
									
										
										
										
											2015-10-22 03:05:01 +08:00
										 |  |  | /* | 
					
						
							|  |  |  | 	MIT License http://www.opensource.org/licenses/mit-license.php
 | 
					
						
							|  |  |  | 	Author Tobias Koppers @sokra | 
					
						
							|  |  |  | */ | 
					
						
							| 
									
										
										
										
											2017-02-23 23:16:56 +08:00
										 |  |  | "use strict"; | 
					
						
							| 
									
										
										
										
											2015-10-22 03:05:01 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-08 18:32:05 +08:00
										 |  |  | const addToSet = (a, b) => { | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 	for (const item of b) { | 
					
						
							|  |  |  | 		if (!a.includes(item)) a.push(item); | 
					
						
							| 
									
										
										
										
											2018-01-22 20:52:43 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-11-08 18:32:05 +08:00
										 |  |  | 	return a; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | const isSubset = (biggerSet, subset) => { | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 	if (biggerSet === true) return true; | 
					
						
							|  |  |  | 	if (subset === true) return false; | 
					
						
							| 
									
										
										
										
											2017-11-08 18:32:05 +08:00
										 |  |  | 	return subset.every(item => biggerSet.indexOf(item) >= 0); | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-23 23:16:56 +08:00
										 |  |  | class FlagDependencyUsagePlugin { | 
					
						
							|  |  |  | 	apply(compiler) { | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 		compiler.hooks.compilation.tap("FlagDependencyUsagePlugin", compilation => { | 
					
						
							|  |  |  | 			compilation.hooks.optimizeModulesAdvanced.tap( | 
					
						
							|  |  |  | 				"FlagDependencyUsagePlugin", | 
					
						
							|  |  |  | 				modules => { | 
					
						
							|  |  |  | 					const processModule = (module, usedExports) => { | 
					
						
							|  |  |  | 						module.used = true; | 
					
						
							|  |  |  | 						if (module.usedExports === true) return; | 
					
						
							|  |  |  | 						else if (usedExports === true) module.usedExports = true; | 
					
						
							|  |  |  | 						else if (Array.isArray(usedExports)) { | 
					
						
							|  |  |  | 							const old = module.usedExports ? module.usedExports.length : -1; | 
					
						
							|  |  |  | 							module.usedExports = addToSet( | 
					
						
							|  |  |  | 								module.usedExports || [], | 
					
						
							|  |  |  | 								usedExports | 
					
						
							|  |  |  | 							); | 
					
						
							|  |  |  | 							if (module.usedExports.length === old) return; | 
					
						
							|  |  |  | 						} else if (Array.isArray(module.usedExports)) return; | 
					
						
							|  |  |  | 						else module.usedExports = false; | 
					
						
							| 
									
										
										
										
											2015-10-22 03:05:01 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 						// for a module without side effects we stop tracking usage here when no export is used
 | 
					
						
							|  |  |  | 						// This module won't be evaluated in this case
 | 
					
						
							|  |  |  | 						if (module.factoryMeta.sideEffectFree) { | 
					
						
							|  |  |  | 							if (module.usedExports === false) return; | 
					
						
							|  |  |  | 							if ( | 
					
						
							|  |  |  | 								Array.isArray(module.usedExports) && | 
					
						
							|  |  |  | 								module.usedExports.length === 0 | 
					
						
							|  |  |  | 							) | 
					
						
							|  |  |  | 								return; | 
					
						
							|  |  |  | 						} | 
					
						
							| 
									
										
										
										
											2017-08-08 15:40:17 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 						queue.push([module, module.usedExports]); | 
					
						
							|  |  |  | 					}; | 
					
						
							| 
									
										
										
										
											2015-10-22 03:05:01 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 					const processDependenciesBlock = (depBlock, usedExports) => { | 
					
						
							|  |  |  | 						for (const dep of depBlock.dependencies) { | 
					
						
							| 
									
										
										
										
											2018-01-22 20:52:43 +08:00
										 |  |  | 							processDependency(dep); | 
					
						
							|  |  |  | 						} | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 						for (const variable of depBlock.variables) { | 
					
						
							|  |  |  | 							for (const dep of variable.dependencies) { | 
					
						
							|  |  |  | 								processDependency(dep); | 
					
						
							|  |  |  | 							} | 
					
						
							|  |  |  | 						} | 
					
						
							|  |  |  | 						for (const block of depBlock.blocks) { | 
					
						
							|  |  |  | 							queue.push([block, usedExports]); | 
					
						
							|  |  |  | 						} | 
					
						
							|  |  |  | 					}; | 
					
						
							| 
									
										
										
										
											2016-12-05 06:47:19 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 					const processDependency = dep => { | 
					
						
							|  |  |  | 						const reference = dep.getReference && dep.getReference(); | 
					
						
							|  |  |  | 						if (!reference) return; | 
					
						
							|  |  |  | 						const module = reference.module; | 
					
						
							|  |  |  | 						const importedNames = reference.importedNames; | 
					
						
							|  |  |  | 						const oldUsed = module.used; | 
					
						
							|  |  |  | 						const oldUsedExports = module.usedExports; | 
					
						
							|  |  |  | 						if ( | 
					
						
							|  |  |  | 							!oldUsed || | 
					
						
							|  |  |  | 							(importedNames && | 
					
						
							|  |  |  | 								(!oldUsedExports || !isSubset(oldUsedExports, importedNames))) | 
					
						
							|  |  |  | 						) { | 
					
						
							|  |  |  | 							processModule(module, importedNames); | 
					
						
							|  |  |  | 						} | 
					
						
							|  |  |  | 					}; | 
					
						
							| 
									
										
										
										
											2015-10-22 03:05:01 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 					for (const module of modules) { | 
					
						
							|  |  |  | 						module.used = false; | 
					
						
							|  |  |  | 					} | 
					
						
							| 
									
										
										
										
											2015-10-22 03:05:01 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 					const queue = []; | 
					
						
							|  |  |  | 					for (const chunk of compilation.chunks) { | 
					
						
							|  |  |  | 						if (chunk.entryModule) { | 
					
						
							|  |  |  | 							processModule(chunk.entryModule, true); | 
					
						
							|  |  |  | 						} | 
					
						
							| 
									
										
										
										
											2017-11-08 18:32:05 +08:00
										 |  |  | 					} | 
					
						
							| 
									
										
										
										
											2017-02-23 23:16:56 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 					while (queue.length) { | 
					
						
							|  |  |  | 						const queueItem = queue.pop(); | 
					
						
							|  |  |  | 						processDependenciesBlock(queueItem[0], queueItem[1]); | 
					
						
							|  |  |  | 					} | 
					
						
							| 
									
										
										
										
											2017-11-08 18:32:05 +08:00
										 |  |  | 				} | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 			); | 
					
						
							| 
									
										
										
										
											2017-02-23 23:16:56 +08:00
										 |  |  | 		}); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | module.exports = FlagDependencyUsagePlugin; |