| 
									
										
										
										
											2016-09-06 05:41:03 +08:00
										 |  |  | /* | 
					
						
							|  |  |  | 	MIT License http://www.opensource.org/licenses/mit-license.php
 | 
					
						
							|  |  |  | 	Author Tobias Koppers @sokra | 
					
						
							|  |  |  | */ | 
					
						
							| 
									
										
										
										
											2017-01-10 18:59:56 +08:00
										 |  |  | "use strict"; | 
					
						
							| 
									
										
										
										
											2016-09-06 05:41:03 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-01 17:42:43 +08:00
										 |  |  | const Queue = require("./util/Queue"); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-08 18:32:05 +08:00
										 |  |  | const addToSet = (a, b) => { | 
					
						
							|  |  |  | 	let changed = false; | 
					
						
							| 
									
										
										
										
											2017-12-01 17:42:43 +08:00
										 |  |  | 	for(const item of b) { | 
					
						
							| 
									
										
										
										
											2017-11-08 18:32:05 +08:00
										 |  |  | 		if(!a.has(item)) { | 
					
						
							|  |  |  | 			a.add(item); | 
					
						
							|  |  |  | 			changed = true; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2017-12-01 17:42:43 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-11-08 18:32:05 +08:00
										 |  |  | 	return changed; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-10 18:59:56 +08:00
										 |  |  | class FlagDependencyExportsPlugin { | 
					
						
							| 
									
										
										
										
											2016-09-06 05:41:03 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-10 18:59:56 +08:00
										 |  |  | 	apply(compiler) { | 
					
						
							| 
									
										
										
										
											2017-12-06 22:01:25 +08:00
										 |  |  | 		compiler.hooks.compilation.tap("FlagDependencyExportsPlugin", (compilation) => { | 
					
						
							|  |  |  | 			compilation.hooks.finishModules.tap("FlagDependencyExportsPlugin", (modules) => { | 
					
						
							| 
									
										
										
										
											2017-12-01 17:42:43 +08:00
										 |  |  | 				const dependencies = new Map(); | 
					
						
							| 
									
										
										
										
											2016-09-06 05:41:03 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-01 17:42:43 +08:00
										 |  |  | 				const queue = new Queue(); | 
					
						
							| 
									
										
										
										
											2017-11-08 18:32:05 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-10 18:59:56 +08:00
										 |  |  | 				let module; | 
					
						
							|  |  |  | 				let moduleWithExports; | 
					
						
							| 
									
										
										
										
											2017-03-14 19:55:19 +08:00
										 |  |  | 				let moduleProvidedExports; | 
					
						
							| 
									
										
										
										
											2016-09-06 05:41:03 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-08 18:32:05 +08:00
										 |  |  | 				const processDependenciesBlock = depBlock => { | 
					
						
							| 
									
										
										
										
											2017-12-01 17:42:43 +08:00
										 |  |  | 					for(const dep of depBlock.dependencies) { | 
					
						
							|  |  |  | 						if(processDependency(dep)) | 
					
						
							|  |  |  | 							return true; | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 					for(const variable of depBlock.variables) { | 
					
						
							|  |  |  | 						for(const dep of variable.dependencies) { | 
					
						
							|  |  |  | 							if(processDependency(dep)) | 
					
						
							|  |  |  | 								return true; | 
					
						
							|  |  |  | 						} | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 					for(const block of depBlock.blocks) { | 
					
						
							|  |  |  | 						if(processDependenciesBlock(block)) | 
					
						
							|  |  |  | 							return true; | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 					return false; | 
					
						
							| 
									
										
										
										
											2017-11-08 18:32:05 +08:00
										 |  |  | 				}; | 
					
						
							| 
									
										
										
										
											2017-01-10 18:59:56 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-08 18:32:05 +08:00
										 |  |  | 				const processDependency = dep => { | 
					
						
							| 
									
										
										
										
											2017-01-10 18:59:56 +08:00
										 |  |  | 					const exportDesc = dep.getExports && dep.getExports(); | 
					
						
							|  |  |  | 					if(!exportDesc) return; | 
					
						
							|  |  |  | 					moduleWithExports = true; | 
					
						
							|  |  |  | 					const exports = exportDesc.exports; | 
					
						
							| 
									
										
										
										
											2017-12-01 17:42:43 +08:00
										 |  |  | 					// break early if it's only in the worst state
 | 
					
						
							| 
									
										
										
										
											2017-12-07 00:39:42 +08:00
										 |  |  | 					if(module.buildMeta.providedExports === true) { | 
					
						
							| 
									
										
										
										
											2017-12-01 17:42:43 +08:00
										 |  |  | 						return true; | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 					// break if it should move to the worst state
 | 
					
						
							|  |  |  | 					if(exports === true) { | 
					
						
							| 
									
										
										
										
											2017-12-07 00:39:42 +08:00
										 |  |  | 						module.buildMeta.providedExports = true; | 
					
						
							| 
									
										
										
										
											2017-12-01 17:42:43 +08:00
										 |  |  | 						notifyDependencies(); | 
					
						
							|  |  |  | 						return true; | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 					// merge in new exports
 | 
					
						
							|  |  |  | 					if(Array.isArray(exports)) { | 
					
						
							|  |  |  | 						if(addToSet(moduleProvidedExports, exports)) { | 
					
						
							|  |  |  | 							notifyDependencies(); | 
					
						
							|  |  |  | 						} | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 					// store dependencies
 | 
					
						
							| 
									
										
										
										
											2017-01-10 18:59:56 +08:00
										 |  |  | 					const exportDeps = exportDesc.dependencies; | 
					
						
							|  |  |  | 					if(exportDeps) { | 
					
						
							| 
									
										
										
										
											2017-12-01 17:42:43 +08:00
										 |  |  | 						for(const exportDependency of exportDeps) { | 
					
						
							|  |  |  | 							// add dependency for this module
 | 
					
						
							|  |  |  | 							const set = dependencies.get(exportDependency); | 
					
						
							|  |  |  | 							if(set === undefined) { | 
					
						
							|  |  |  | 								dependencies.set(exportDependency, new Set([module])); | 
					
						
							|  |  |  | 							} else { | 
					
						
							|  |  |  | 								set.add(module); | 
					
						
							| 
									
										
										
										
											2017-02-05 10:44:18 +08:00
										 |  |  | 							} | 
					
						
							| 
									
										
										
										
											2016-09-09 20:20:29 +08:00
										 |  |  | 						} | 
					
						
							| 
									
										
										
										
											2016-11-21 08:00:25 +08:00
										 |  |  | 					} | 
					
						
							| 
									
										
										
										
											2017-12-01 17:42:43 +08:00
										 |  |  | 					return false; | 
					
						
							| 
									
										
										
										
											2017-11-08 18:32:05 +08:00
										 |  |  | 				}; | 
					
						
							| 
									
										
										
										
											2016-09-09 20:50:14 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-08 18:32:05 +08:00
										 |  |  | 				const notifyDependencies = () => { | 
					
						
							| 
									
										
										
										
											2017-12-01 17:42:43 +08:00
										 |  |  | 					const deps = dependencies.get(module); | 
					
						
							|  |  |  | 					if(deps !== undefined) { | 
					
						
							|  |  |  | 						for(const dep of deps) { | 
					
						
							|  |  |  | 							queue.enqueue(dep); | 
					
						
							|  |  |  | 						} | 
					
						
							| 
									
										
										
										
											2017-01-10 18:59:56 +08:00
										 |  |  | 					} | 
					
						
							| 
									
										
										
										
											2017-11-08 18:32:05 +08:00
										 |  |  | 				}; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-01 17:42:43 +08:00
										 |  |  | 				// Start with all modules without provided exports
 | 
					
						
							|  |  |  | 				for(const module of modules) { | 
					
						
							| 
									
										
										
										
											2017-12-07 00:39:42 +08:00
										 |  |  | 					if(!module.buildMeta.providedExports) { | 
					
						
							| 
									
										
										
										
											2017-12-01 17:42:43 +08:00
										 |  |  | 						queue.enqueue(module); | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				while(queue.length > 0) { | 
					
						
							|  |  |  | 					module = queue.dequeue(); | 
					
						
							| 
									
										
										
										
											2017-01-10 18:59:56 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-07 00:39:42 +08:00
										 |  |  | 					if(module.buildMeta.providedExports !== true) { | 
					
						
							| 
									
										
										
										
											2017-12-23 01:23:20 +08:00
										 |  |  | 						moduleWithExports = module.buildMeta && module.buildMeta.exportsType; | 
					
						
							| 
									
										
										
										
											2017-12-07 00:39:42 +08:00
										 |  |  | 						moduleProvidedExports = Array.isArray(module.buildMeta.providedExports) ? new Set(module.buildMeta.providedExports) : new Set(); | 
					
						
							| 
									
										
										
										
											2017-11-08 18:32:05 +08:00
										 |  |  | 						processDependenciesBlock(module); | 
					
						
							|  |  |  | 						if(!moduleWithExports) { | 
					
						
							| 
									
										
										
										
											2017-12-07 00:39:42 +08:00
										 |  |  | 							module.buildMeta.providedExports = true; | 
					
						
							| 
									
										
										
										
											2017-11-08 18:32:05 +08:00
										 |  |  | 							notifyDependencies(); | 
					
						
							| 
									
										
										
										
											2017-12-07 00:39:42 +08:00
										 |  |  | 						} else if(module.buildMeta.providedExports !== true) { | 
					
						
							|  |  |  | 							module.buildMeta.providedExports = Array.from(moduleProvidedExports); | 
					
						
							| 
									
										
										
										
											2017-11-08 18:32:05 +08:00
										 |  |  | 						} | 
					
						
							| 
									
										
										
										
											2017-01-10 18:59:56 +08:00
										 |  |  | 					} | 
					
						
							| 
									
										
										
										
											2017-11-08 18:32:05 +08:00
										 |  |  | 				} | 
					
						
							|  |  |  | 			}); | 
					
						
							| 
									
										
										
										
											2017-12-07 00:39:42 +08:00
										 |  |  | 			const providedExportsCache = new WeakMap(); | 
					
						
							|  |  |  | 			compilation.hooks.rebuildModule.tap("FlagDependencyExportsPlugin", module => { | 
					
						
							|  |  |  | 				providedExportsCache.set(module, module.buildMeta.providedExports); | 
					
						
							|  |  |  | 			}); | 
					
						
							|  |  |  | 			compilation.hooks.finishRebuildingModule.tap("FlagDependencyExportsPlugin", module => { | 
					
						
							|  |  |  | 				module.buildMeta.providedExports = providedExportsCache.get(module); | 
					
						
							|  |  |  | 			}); | 
					
						
							| 
									
										
										
										
											2016-09-06 05:41:03 +08:00
										 |  |  | 		}); | 
					
						
							| 
									
										
										
										
											2017-01-10 18:59:56 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2016-09-06 05:41:03 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-10 18:59:56 +08:00
										 |  |  | module.exports = FlagDependencyExportsPlugin; |