| 
									
										
										
										
											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; | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 	for (const item of b) { | 
					
						
							|  |  |  | 		if (!a.has(item)) { | 
					
						
							| 
									
										
										
										
											2017-11-08 18:32:05 +08:00
										 |  |  | 			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 { | 
					
						
							|  |  |  | 	apply(compiler) { | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 		compiler.hooks.compilation.tap( | 
					
						
							|  |  |  | 			"FlagDependencyExportsPlugin", | 
					
						
							|  |  |  | 			compilation => { | 
					
						
							|  |  |  | 				compilation.hooks.finishModules.tap( | 
					
						
							|  |  |  | 					"FlagDependencyExportsPlugin", | 
					
						
							|  |  |  | 					modules => { | 
					
						
							|  |  |  | 						const dependencies = new Map(); | 
					
						
							| 
									
										
										
										
											2016-09-06 05:41:03 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 						const queue = new Queue(); | 
					
						
							| 
									
										
										
										
											2017-11-08 18:32:05 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 						let module; | 
					
						
							|  |  |  | 						let moduleWithExports; | 
					
						
							|  |  |  | 						let moduleProvidedExports; | 
					
						
							| 
									
										
										
										
											2016-09-06 05:41:03 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 						const processDependenciesBlock = depBlock => { | 
					
						
							|  |  |  | 							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; | 
					
						
							|  |  |  | 						}; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 						const processDependency = dep => { | 
					
						
							|  |  |  | 							const exportDesc = dep.getExports && dep.getExports(); | 
					
						
							|  |  |  | 							if (!exportDesc) return; | 
					
						
							|  |  |  | 							moduleWithExports = true; | 
					
						
							|  |  |  | 							const exports = exportDesc.exports; | 
					
						
							|  |  |  | 							// break early if it's only in the worst state
 | 
					
						
							|  |  |  | 							if (module.buildMeta.providedExports === true) { | 
					
						
							| 
									
										
										
										
											2017-12-01 17:42:43 +08:00
										 |  |  | 								return true; | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 							} | 
					
						
							|  |  |  | 							// break if it should move to the worst state
 | 
					
						
							|  |  |  | 							if (exports === true) { | 
					
						
							|  |  |  | 								module.buildMeta.providedExports = true; | 
					
						
							|  |  |  | 								notifyDependencies(); | 
					
						
							|  |  |  | 								return true; | 
					
						
							|  |  |  | 							} | 
					
						
							|  |  |  | 							// merge in new exports
 | 
					
						
							|  |  |  | 							if (Array.isArray(exports)) { | 
					
						
							|  |  |  | 								if (addToSet(moduleProvidedExports, exports)) { | 
					
						
							|  |  |  | 									notifyDependencies(); | 
					
						
							|  |  |  | 								} | 
					
						
							|  |  |  | 							} | 
					
						
							|  |  |  | 							// store dependencies
 | 
					
						
							|  |  |  | 							const exportDeps = exportDesc.dependencies; | 
					
						
							|  |  |  | 							if (exportDeps) { | 
					
						
							|  |  |  | 								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); | 
					
						
							|  |  |  | 									} | 
					
						
							|  |  |  | 								} | 
					
						
							|  |  |  | 							} | 
					
						
							|  |  |  | 							return false; | 
					
						
							|  |  |  | 						}; | 
					
						
							| 
									
										
										
										
											2017-01-10 18:59:56 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 						const notifyDependencies = () => { | 
					
						
							|  |  |  | 							const deps = dependencies.get(module); | 
					
						
							|  |  |  | 							if (deps !== undefined) { | 
					
						
							|  |  |  | 								for (const dep of deps) { | 
					
						
							|  |  |  | 									queue.enqueue(dep); | 
					
						
							|  |  |  | 								} | 
					
						
							| 
									
										
										
										
											2017-02-05 10:44:18 +08:00
										 |  |  | 							} | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 						}; | 
					
						
							| 
									
										
										
										
											2016-09-09 20:50:14 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 						// Start with all modules without provided exports
 | 
					
						
							|  |  |  | 						for (const module of modules) { | 
					
						
							|  |  |  | 							if (!module.buildMeta.providedExports) { | 
					
						
							|  |  |  | 								queue.enqueue(module); | 
					
						
							|  |  |  | 							} | 
					
						
							| 
									
										
										
										
											2017-12-01 17:42:43 +08:00
										 |  |  | 						} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 						while (queue.length > 0) { | 
					
						
							|  |  |  | 							module = queue.dequeue(); | 
					
						
							| 
									
										
										
										
											2017-01-10 18:59:56 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 							if (module.buildMeta.providedExports !== true) { | 
					
						
							|  |  |  | 								moduleWithExports = | 
					
						
							|  |  |  | 									module.buildMeta && module.buildMeta.exportsType; | 
					
						
							|  |  |  | 								moduleProvidedExports = Array.isArray( | 
					
						
							|  |  |  | 									module.buildMeta.providedExports | 
					
						
							|  |  |  | 								) | 
					
						
							|  |  |  | 									? new Set(module.buildMeta.providedExports) | 
					
						
							|  |  |  | 									: new Set(); | 
					
						
							|  |  |  | 								processDependenciesBlock(module); | 
					
						
							|  |  |  | 								if (!moduleWithExports) { | 
					
						
							|  |  |  | 									module.buildMeta.providedExports = true; | 
					
						
							|  |  |  | 									notifyDependencies(); | 
					
						
							|  |  |  | 								} 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
										 |  |  | 					} | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +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); | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 				); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		); | 
					
						
							| 
									
										
										
										
											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; |