| 
									
										
										
										
											2013-01-31 01:49:25 +08:00
										 |  |  | /* | 
					
						
							| 
									
										
										
										
											2017-01-24 03:31:53 +08:00
										 |  |  | 	MIT License http://www.opensource.org/licenses/mit-license.php
 | 
					
						
							|  |  |  | 	Author Tobias Koppers @sokra | 
					
						
							|  |  |  | 	*/ | 
					
						
							| 
									
										
										
										
											2017-01-06 01:00:36 +08:00
										 |  |  | "use strict"; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-05 21:05:00 +08:00
										 |  |  | const asyncLib = require("async"); | 
					
						
							| 
									
										
										
										
											2017-11-10 18:02:45 +08:00
										 |  |  | const util = require("util"); | 
					
						
							| 
									
										
										
										
											2017-11-27 22:27:30 +08:00
										 |  |  | const Tapable = require("tapable").Tapable; | 
					
						
							|  |  |  | const SyncHook = require("tapable").SyncHook; | 
					
						
							|  |  |  | const SyncBailHook = require("tapable").SyncBailHook; | 
					
						
							|  |  |  | const SyncWaterfallHook = require("tapable").SyncWaterfallHook; | 
					
						
							|  |  |  | const AsyncSeriesHook = require("tapable").AsyncSeriesHook; | 
					
						
							| 
									
										
										
										
											2017-01-06 01:00:36 +08:00
										 |  |  | const EntryModuleNotFoundError = require("./EntryModuleNotFoundError"); | 
					
						
							|  |  |  | const ModuleNotFoundError = require("./ModuleNotFoundError"); | 
					
						
							|  |  |  | const ModuleDependencyWarning = require("./ModuleDependencyWarning"); | 
					
						
							| 
									
										
										
										
											2017-01-10 00:11:34 +08:00
										 |  |  | const ModuleDependencyError = require("./ModuleDependencyError"); | 
					
						
							| 
									
										
										
										
											2017-01-06 01:00:36 +08:00
										 |  |  | const Module = require("./Module"); | 
					
						
							|  |  |  | const Chunk = require("./Chunk"); | 
					
						
							|  |  |  | const Entrypoint = require("./Entrypoint"); | 
					
						
							|  |  |  | const MainTemplate = require("./MainTemplate"); | 
					
						
							|  |  |  | const ChunkTemplate = require("./ChunkTemplate"); | 
					
						
							|  |  |  | const HotUpdateChunkTemplate = require("./HotUpdateChunkTemplate"); | 
					
						
							|  |  |  | const ModuleTemplate = require("./ModuleTemplate"); | 
					
						
							|  |  |  | const Dependency = require("./Dependency"); | 
					
						
							|  |  |  | const ChunkRenderError = require("./ChunkRenderError"); | 
					
						
							| 
									
										
										
										
											2017-10-17 15:06:05 +08:00
										 |  |  | const AsyncDependencyToInitialChunkWarning = require("./AsyncDependencyToInitialChunkWarning"); | 
					
						
							| 
									
										
										
										
											2017-01-06 01:00:36 +08:00
										 |  |  | const CachedSource = require("webpack-sources").CachedSource; | 
					
						
							| 
									
										
										
										
											2017-04-06 19:52:06 +08:00
										 |  |  | const Stats = require("./Stats"); | 
					
						
							| 
									
										
										
										
											2017-08-11 22:11:17 +08:00
										 |  |  | const Semaphore = require("./util/Semaphore"); | 
					
						
							| 
									
										
										
										
											2017-11-23 17:59:29 +08:00
										 |  |  | const createHash = require("./util/createHash"); | 
					
						
							| 
									
										
										
										
											2017-10-13 01:12:48 +08:00
										 |  |  | const Queue = require("./util/Queue"); | 
					
						
							| 
									
										
										
										
											2017-11-06 23:41:26 +08:00
										 |  |  | const SortableSet = require("./util/SortableSet"); | 
					
						
							| 
									
										
										
										
											2013-01-31 01:49:25 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-08 18:32:05 +08:00
										 |  |  | const byId = (a, b) => { | 
					
						
							| 
									
										
										
										
											2017-01-06 01:00:36 +08:00
										 |  |  | 	if(a.id < b.id) return -1; | 
					
						
							|  |  |  | 	if(a.id > b.id) return 1; | 
					
						
							|  |  |  | 	return 0; | 
					
						
							| 
									
										
										
										
											2017-11-08 18:32:05 +08:00
										 |  |  | }; | 
					
						
							| 
									
										
										
										
											2015-08-18 19:35:57 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-08 18:32:05 +08:00
										 |  |  | const iterationBlockVariable = (variables, fn) => { | 
					
						
							| 
									
										
										
										
											2017-03-02 22:09:09 +08:00
										 |  |  | 	for(let indexVariable = 0; indexVariable < variables.length; indexVariable++) { | 
					
						
							|  |  |  | 		let varDep = variables[indexVariable].dependencies; | 
					
						
							|  |  |  | 		for(let indexVDep = 0; indexVDep < varDep.length; indexVDep++) { | 
					
						
							| 
									
										
										
										
											2017-01-24 02:52:20 +08:00
										 |  |  | 			fn(varDep[indexVDep]); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-11-08 18:32:05 +08:00
										 |  |  | }; | 
					
						
							| 
									
										
										
										
											2017-01-24 02:52:20 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-08 18:32:05 +08:00
										 |  |  | const iterationOfArrayCallback = (arr, fn) => { | 
					
						
							| 
									
										
										
										
											2017-03-02 22:09:09 +08:00
										 |  |  | 	for(let index = 0; index < arr.length; index++) { | 
					
						
							| 
									
										
										
										
											2017-01-24 02:52:20 +08:00
										 |  |  | 		fn(arr[index]); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-11-08 18:32:05 +08:00
										 |  |  | }; | 
					
						
							| 
									
										
										
										
											2017-01-24 02:52:20 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 23:41:26 +08:00
										 |  |  | function addAllToSet(set, otherSet) { | 
					
						
							|  |  |  | 	for(const item of otherSet) { | 
					
						
							|  |  |  | 		set.add(item); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-06 01:00:36 +08:00
										 |  |  | class Compilation extends Tapable { | 
					
						
							|  |  |  | 	constructor(compiler) { | 
					
						
							|  |  |  | 		super(); | 
					
						
							| 
									
										
										
										
											2017-11-27 22:27:30 +08:00
										 |  |  | 		this.hooks = { | 
					
						
							|  |  |  | 			buildModule: new SyncHook(["module"]), | 
					
						
							|  |  |  | 			failedModule: new SyncHook(["module", "error"]), | 
					
						
							|  |  |  | 			succeedModule: new SyncHook(["module"]), | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			finishModules: new SyncHook(["modules"]), | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			unseal: new SyncHook([]), | 
					
						
							|  |  |  | 			seal: new SyncHook([]), | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			optimizeDependenciesBasic: new SyncBailHook(["modules"]), | 
					
						
							|  |  |  | 			optimizeDependencies: new SyncBailHook(["modules"]), | 
					
						
							|  |  |  | 			optimizeDependenciesAdvanced: new SyncBailHook(["modules"]), | 
					
						
							|  |  |  | 			afterOptimizeDependencies: new SyncHook(["modules"]), | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			optimize: new SyncHook([]), | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			optimizeModulesBasic: new SyncBailHook(["modules"]), | 
					
						
							|  |  |  | 			optimizeModules: new SyncBailHook(["modules"]), | 
					
						
							|  |  |  | 			optimizeModulesAdvanced: new SyncBailHook(["modules"]), | 
					
						
							|  |  |  | 			afterOptimizeModules: new SyncHook(["modules"]), | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			optimizeChunksBasic: new SyncBailHook(["chunks"]), | 
					
						
							|  |  |  | 			optimizeChunks: new SyncBailHook(["chunks"]), | 
					
						
							|  |  |  | 			optimizeChunksAdvanced: new SyncBailHook(["chunks"]), | 
					
						
							|  |  |  | 			afterOptimizeChunks: new SyncHook(["chunks"]), | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			optimizeTree: new AsyncSeriesHook(["chunks", "modules"]), | 
					
						
							|  |  |  | 			afterOptimizeTree: new SyncHook(["chunks", "modules"]), | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			optimizeChunkModulesBasic: new SyncBailHook(["chunks", "modules"]), | 
					
						
							|  |  |  | 			optimizeChunkModules: new SyncBailHook(["chunks", "modules"]), | 
					
						
							|  |  |  | 			optimizeChunkModulesAdvanced: new SyncBailHook(["chunks", "modules"]), | 
					
						
							|  |  |  | 			afterOptimizeChunkModules: new SyncHook(["chunks", "modules"]), | 
					
						
							|  |  |  | 			shouldRecord: new SyncBailHook([]), | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			reviveModules: new SyncHook(["modules", "records"]), | 
					
						
							|  |  |  | 			optimizeModuleOrder: new SyncHook(["modules"]), | 
					
						
							|  |  |  | 			advancedOptimizeModuleOrder: new SyncHook(["modules"]), | 
					
						
							|  |  |  | 			beforeModuleIds: new SyncHook(["modules"]), | 
					
						
							|  |  |  | 			moduleIds: new SyncHook(["modules"]), | 
					
						
							|  |  |  | 			optimizeModuleIds: new SyncHook(["modules"]), | 
					
						
							|  |  |  | 			afterOptimizeModuleIds: new SyncHook(["modules"]), | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			reviveChunks: new SyncHook(["chunks", "records"]), | 
					
						
							|  |  |  | 			optimizeChunkOrder: new SyncHook(["chunks"]), | 
					
						
							|  |  |  | 			beforeChunkIds: new SyncHook(["chunks"]), | 
					
						
							|  |  |  | 			optimizeChunkIds: new SyncHook(["chunks"]), | 
					
						
							|  |  |  | 			afterOptimizeChunkIds: new SyncHook(["chunks"]), | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			recordModules: new SyncHook(["modules", "records"]), | 
					
						
							|  |  |  | 			recordChunks: new SyncHook(["chunks", "records"]), | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			beforeHash: new SyncHook([]), | 
					
						
							|  |  |  | 			afterHash: new SyncHook([]), | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			recordHash: new SyncHook(["records"]), | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			record: new SyncHook(["compilation", "records"]), | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			beforeModuleAssets: new SyncHook([]), | 
					
						
							|  |  |  | 			shouldGenerateChunkAssets: new SyncBailHook([]), | 
					
						
							|  |  |  | 			beforeChunkAssets: new SyncHook([]), | 
					
						
							|  |  |  | 			additionalChunkAssets: new SyncHook(["chunks"]), | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			records: new SyncHook(["compilation", "records"]), | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			additionalAssets: new AsyncSeriesHook([]), | 
					
						
							|  |  |  | 			optimizeChunkAssets: new AsyncSeriesHook(["chunks"]), | 
					
						
							|  |  |  | 			afterOptimizeChunkAssets: new SyncHook(["chunks"]), | 
					
						
							|  |  |  | 			optimizeAssets: new AsyncSeriesHook(["assets"]), | 
					
						
							|  |  |  | 			afterOptimizeAssets: new SyncHook(["assets"]), | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			needAdditionalSeal: new SyncBailHook([]), | 
					
						
							|  |  |  | 			afterSeal: new AsyncSeriesHook([]), | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			chunkHash: new SyncHook(["chunk", "chunkHash"]), | 
					
						
							|  |  |  | 			moduleAsset: new SyncHook(["module", "filename"]), | 
					
						
							|  |  |  | 			chunkAsset: new SyncHook(["chunk", "filename"]), | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			assetPath: new SyncWaterfallHook(["filename", "data"]), // TODO MainTemplate
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			needAdditionalPass: new SyncBailHook([]), | 
					
						
							|  |  |  | 			childCompiler: new SyncHook(["childCompiler", "compilerName", "compilerIndex"]), | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			// TODO the following hooks are weirdly located here
 | 
					
						
							|  |  |  | 			// TODO move them for webpack 5
 | 
					
						
							|  |  |  | 			normalModuleLoader: new SyncHook(["loaderContext", "module"]), | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			optimizeExtractedChunksBasic: new SyncBailHook(["chunks"]), | 
					
						
							|  |  |  | 			optimizeExtractedChunks: new SyncBailHook(["chunks"]), | 
					
						
							|  |  |  | 			optimizeExtractedChunksAdvanced: new SyncBailHook(["chunks"]), | 
					
						
							|  |  |  | 			afterOptimizeExtractedChunks: new SyncHook(["chunks"]), | 
					
						
							|  |  |  | 		}; | 
					
						
							|  |  |  | 		this._pluginCompat.tap("Compilation", options => { | 
					
						
							|  |  |  | 			switch(options.name) { | 
					
						
							|  |  |  | 				case "optimize-tree": | 
					
						
							|  |  |  | 				case "additional-assets": | 
					
						
							|  |  |  | 				case "optimize-chunk-assets": | 
					
						
							|  |  |  | 				case "optimize-assets": | 
					
						
							|  |  |  | 				case "after-seal": | 
					
						
							|  |  |  | 					options.async = true; | 
					
						
							|  |  |  | 					break; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		}); | 
					
						
							| 
									
										
										
										
											2017-01-06 01:00:36 +08:00
										 |  |  | 		this.compiler = compiler; | 
					
						
							| 
									
										
										
										
											2017-11-17 21:26:23 +08:00
										 |  |  | 		this.resolverFactory = compiler.resolverFactory; | 
					
						
							| 
									
										
										
										
											2017-01-06 01:00:36 +08:00
										 |  |  | 		this.inputFileSystem = compiler.inputFileSystem; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		const options = this.options = compiler.options; | 
					
						
							|  |  |  | 		this.outputOptions = options && options.output; | 
					
						
							|  |  |  | 		this.bail = options && options.bail; | 
					
						
							|  |  |  | 		this.profile = options && options.profile; | 
					
						
							|  |  |  | 		this.performance = options && options.performance; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		this.mainTemplate = new MainTemplate(this.outputOptions); | 
					
						
							|  |  |  | 		this.chunkTemplate = new ChunkTemplate(this.outputOptions); | 
					
						
							|  |  |  | 		this.hotUpdateChunkTemplate = new HotUpdateChunkTemplate(this.outputOptions); | 
					
						
							| 
									
										
										
										
											2017-10-30 20:56:57 +08:00
										 |  |  | 		this.moduleTemplates = { | 
					
						
							|  |  |  | 			javascript: new ModuleTemplate(this.outputOptions), | 
					
						
							|  |  |  | 			webassembly: new ModuleTemplate(this.outputOptions) | 
					
						
							|  |  |  | 		}; | 
					
						
							| 
									
										
										
										
											2017-01-06 01:00:36 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-11 22:11:17 +08:00
										 |  |  | 		this.semaphore = new Semaphore(options.parallelism || 100); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-06 01:00:36 +08:00
										 |  |  | 		this.entries = []; | 
					
						
							|  |  |  | 		this.preparedChunks = []; | 
					
						
							|  |  |  | 		this.entrypoints = {}; | 
					
						
							|  |  |  | 		this.chunks = []; | 
					
						
							|  |  |  | 		this.namedChunks = {}; | 
					
						
							|  |  |  | 		this.modules = []; | 
					
						
							| 
									
										
										
										
											2017-11-06 20:02:35 +08:00
										 |  |  | 		this._modules = new Map(); | 
					
						
							| 
									
										
										
										
											2017-01-06 01:00:36 +08:00
										 |  |  | 		this.cache = null; | 
					
						
							|  |  |  | 		this.records = null; | 
					
						
							|  |  |  | 		this.nextFreeModuleIndex = undefined; | 
					
						
							|  |  |  | 		this.nextFreeModuleIndex2 = undefined; | 
					
						
							|  |  |  | 		this.additionalChunkAssets = []; | 
					
						
							|  |  |  | 		this.assets = {}; | 
					
						
							|  |  |  | 		this.errors = []; | 
					
						
							|  |  |  | 		this.warnings = []; | 
					
						
							|  |  |  | 		this.children = []; | 
					
						
							|  |  |  | 		this.dependencyFactories = new Map(); | 
					
						
							|  |  |  | 		this.dependencyTemplates = new Map(); | 
					
						
							| 
									
										
										
										
											2017-07-14 18:50:39 +08:00
										 |  |  | 		this.dependencyTemplates.set("hash", ""); | 
					
						
							| 
									
										
										
										
											2017-04-13 19:43:51 +08:00
										 |  |  | 		this.childrenCounters = {}; | 
					
						
							| 
									
										
										
										
											2017-11-06 20:02:35 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		this._buildingModules = new Map(); | 
					
						
							|  |  |  | 		this._rebuildingModules = new Map(); | 
					
						
							| 
									
										
										
										
											2017-01-06 01:00:36 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-12-22 23:10:23 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-06 19:52:06 +08:00
										 |  |  | 	getStats() { | 
					
						
							|  |  |  | 		return new Stats(this); | 
					
						
							| 
									
										
										
										
											2017-01-06 01:00:36 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-12-22 23:10:23 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-06 01:00:36 +08:00
										 |  |  | 	templatesPlugin(name, fn) { | 
					
						
							|  |  |  | 		this.mainTemplate.plugin(name, fn); | 
					
						
							|  |  |  | 		this.chunkTemplate.plugin(name, fn); | 
					
						
							| 
									
										
										
										
											2014-06-04 03:03:21 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2013-05-08 19:28:54 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-06 01:00:36 +08:00
										 |  |  | 	addModule(module, cacheGroup) { | 
					
						
							|  |  |  | 		const identifier = module.identifier(); | 
					
						
							| 
									
										
										
										
											2017-11-06 20:02:35 +08:00
										 |  |  | 		if(this._modules.get(identifier)) { | 
					
						
							| 
									
										
										
										
											2017-01-06 01:00:36 +08:00
										 |  |  | 			return false; | 
					
						
							| 
									
										
										
										
											2013-01-31 01:49:25 +08:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2017-01-26 03:39:24 +08:00
										 |  |  | 		const cacheName = (cacheGroup || "m") + identifier; | 
					
						
							|  |  |  | 		if(this.cache && this.cache[cacheName]) { | 
					
						
							|  |  |  | 			const cacheModule = this.cache[cacheName]; | 
					
						
							| 
									
										
										
										
											2013-02-01 01:00:22 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-06 01:00:36 +08:00
										 |  |  | 			let rebuild = true; | 
					
						
							| 
									
										
										
										
											2017-11-06 20:02:35 +08:00
										 |  |  | 			if(this.fileTimestamps && this.contextTimestamps) { | 
					
						
							| 
									
										
										
										
											2017-01-06 01:00:36 +08:00
										 |  |  | 				rebuild = cacheModule.needRebuild(this.fileTimestamps, this.contextTimestamps); | 
					
						
							| 
									
										
										
										
											2014-06-04 03:03:21 +08:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2015-07-08 20:15:21 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-06 01:00:36 +08:00
										 |  |  | 			if(!rebuild) { | 
					
						
							|  |  |  | 				cacheModule.disconnect(); | 
					
						
							| 
									
										
										
										
											2017-11-06 20:02:35 +08:00
										 |  |  | 				this._modules.set(identifier, cacheModule); | 
					
						
							| 
									
										
										
										
											2017-01-06 01:00:36 +08:00
										 |  |  | 				this.modules.push(cacheModule); | 
					
						
							| 
									
										
										
										
											2017-11-09 03:49:41 +08:00
										 |  |  | 				cacheModule.errors.forEach(err => this.errors.push(err)); | 
					
						
							|  |  |  | 				cacheModule.warnings.forEach(err => this.warnings.push(err)); | 
					
						
							| 
									
										
										
										
											2017-01-06 01:00:36 +08:00
										 |  |  | 				return cacheModule; | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2017-11-06 20:02:35 +08:00
										 |  |  | 			module.unbuild(); | 
					
						
							| 
									
										
										
										
											2014-06-04 03:03:21 +08:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2017-11-06 20:02:35 +08:00
										 |  |  | 		this._modules.set(identifier, module); | 
					
						
							| 
									
										
										
										
											2017-01-06 01:00:36 +08:00
										 |  |  | 		if(this.cache) { | 
					
						
							| 
									
										
										
										
											2017-01-26 03:39:24 +08:00
										 |  |  | 			this.cache[cacheName] = module; | 
					
						
							| 
									
										
										
										
											2014-06-04 03:03:21 +08:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2017-01-06 01:00:36 +08:00
										 |  |  | 		this.modules.push(module); | 
					
						
							|  |  |  | 		return true; | 
					
						
							| 
									
										
										
										
											2013-01-31 01:49:25 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-01-06 01:00:36 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	getModule(module) { | 
					
						
							|  |  |  | 		const identifier = module.identifier(); | 
					
						
							| 
									
										
										
										
											2017-11-06 20:02:35 +08:00
										 |  |  | 		return this._modules.get(identifier); | 
					
						
							| 
									
										
										
										
											2013-01-31 01:49:25 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-06 01:00:36 +08:00
										 |  |  | 	findModule(identifier) { | 
					
						
							| 
									
										
										
										
											2017-11-06 20:02:35 +08:00
										 |  |  | 		return this._modules.get(identifier); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	waitForBuildingFinished(module, callback) { | 
					
						
							|  |  |  | 		let callbackList = this._buildingModules.get(module); | 
					
						
							|  |  |  | 		if(callbackList) { | 
					
						
							|  |  |  | 			callbackList.push(() => callback()); | 
					
						
							|  |  |  | 		} else { | 
					
						
							|  |  |  | 			process.nextTick(callback); | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2017-01-06 01:00:36 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	buildModule(module, optional, origin, dependencies, thisCallback) { | 
					
						
							| 
									
										
										
										
											2017-11-27 22:27:30 +08:00
										 |  |  | 		this.hooks.buildModule.call(module); | 
					
						
							| 
									
										
										
										
											2017-11-06 20:02:35 +08:00
										 |  |  | 		let callbackList = this._buildingModules.get(module); | 
					
						
							|  |  |  | 		if(callbackList) { | 
					
						
							|  |  |  | 			callbackList.push(thisCallback); | 
					
						
							|  |  |  | 			return; | 
					
						
							| 
									
										
										
										
											2017-01-06 01:00:36 +08:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2017-11-06 20:02:35 +08:00
										 |  |  | 		this._buildingModules.set(module, callbackList = [thisCallback]); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		const callback = err => { | 
					
						
							|  |  |  | 			this._buildingModules.delete(module); | 
					
						
							|  |  |  | 			callbackList.forEach(cb => cb(err)); | 
					
						
							|  |  |  | 		}; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-17 21:26:23 +08:00
										 |  |  | 		module.build(this.options, this, this.resolverFactory.get("normal", module.resolveOptions), this.inputFileSystem, (error) => { | 
					
						
							| 
									
										
										
										
											2017-03-02 22:09:09 +08:00
										 |  |  | 			const errors = module.errors; | 
					
						
							|  |  |  | 			for(let indexError = 0; indexError < errors.length; indexError++) { | 
					
						
							|  |  |  | 				const err = errors[indexError]; | 
					
						
							| 
									
										
										
										
											2017-01-06 01:00:36 +08:00
										 |  |  | 				err.origin = origin; | 
					
						
							|  |  |  | 				err.dependencies = dependencies; | 
					
						
							|  |  |  | 				if(optional) | 
					
						
							|  |  |  | 					this.warnings.push(err); | 
					
						
							|  |  |  | 				else | 
					
						
							|  |  |  | 					this.errors.push(err); | 
					
						
							| 
									
										
										
										
											2017-01-24 02:52:20 +08:00
										 |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-02 22:09:09 +08:00
										 |  |  | 			const warnings = module.warnings; | 
					
						
							|  |  |  | 			for(let indexWarning = 0; indexWarning < warnings.length; indexWarning++) { | 
					
						
							|  |  |  | 				const war = warnings[indexWarning]; | 
					
						
							| 
									
										
										
										
											2017-01-24 02:52:20 +08:00
										 |  |  | 				war.origin = origin; | 
					
						
							|  |  |  | 				war.dependencies = dependencies; | 
					
						
							|  |  |  | 				this.warnings.push(war); | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2017-01-06 01:00:36 +08:00
										 |  |  | 			module.dependencies.sort(Dependency.compare); | 
					
						
							| 
									
										
										
										
											2017-01-24 02:52:20 +08:00
										 |  |  | 			if(error) { | 
					
						
							| 
									
										
										
										
											2017-11-27 22:27:30 +08:00
										 |  |  | 				this.hooks.failedModule.call(module, error); | 
					
						
							| 
									
										
										
										
											2017-01-24 02:52:20 +08:00
										 |  |  | 				return callback(error); | 
					
						
							| 
									
										
										
										
											2013-01-31 01:49:25 +08:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2017-11-27 22:27:30 +08:00
										 |  |  | 			this.hooks.succeedModule.call(module); | 
					
						
							| 
									
										
										
										
											2017-01-06 01:00:36 +08:00
										 |  |  | 			return callback(); | 
					
						
							|  |  |  | 		}); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-07-08 20:15:21 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-06 01:00:36 +08:00
										 |  |  | 	processModuleDependencies(module, callback) { | 
					
						
							| 
									
										
										
										
											2017-11-19 07:22:38 +08:00
										 |  |  | 		const dependencies = new Map(); | 
					
						
							| 
									
										
										
										
											2017-01-06 01:00:36 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-08 18:32:05 +08:00
										 |  |  | 		const addDependency = dep => { | 
					
						
							| 
									
										
										
										
											2017-11-19 07:22:38 +08:00
										 |  |  | 			const resourceIdent = dep.getResourceIdentifier(); | 
					
						
							|  |  |  | 			if(resourceIdent) { | 
					
						
							|  |  |  | 				const factory = this.dependencyFactories.get(dep.constructor); | 
					
						
							| 
									
										
										
										
											2017-11-19 16:06:40 +08:00
										 |  |  | 				if(factory === undefined) | 
					
						
							|  |  |  | 					throw new Error(`No module factory available for dependency type: ${dep.constructor.name}`); | 
					
						
							| 
									
										
										
										
											2017-11-19 07:22:38 +08:00
										 |  |  | 				let innerMap = dependencies.get(factory); | 
					
						
							|  |  |  | 				if(innerMap === undefined) | 
					
						
							|  |  |  | 					dependencies.set(factory, innerMap = new Map()); | 
					
						
							|  |  |  | 				let list = innerMap.get(resourceIdent); | 
					
						
							|  |  |  | 				if(list === undefined) | 
					
						
							|  |  |  | 					innerMap.set(resourceIdent, list = []); | 
					
						
							|  |  |  | 				list.push(dep); | 
					
						
							| 
									
										
										
										
											2014-06-04 03:03:21 +08:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2017-11-08 18:32:05 +08:00
										 |  |  | 		}; | 
					
						
							| 
									
										
										
										
											2017-01-06 01:00:36 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-08 18:32:05 +08:00
										 |  |  | 		const addDependenciesBlock = block => { | 
					
						
							| 
									
										
										
										
											2017-01-06 01:00:36 +08:00
										 |  |  | 			if(block.dependencies) { | 
					
						
							| 
									
										
										
										
											2017-01-24 02:52:20 +08:00
										 |  |  | 				iterationOfArrayCallback(block.dependencies, addDependency); | 
					
						
							| 
									
										
										
										
											2014-06-04 03:03:21 +08:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2017-01-06 01:00:36 +08:00
										 |  |  | 			if(block.blocks) { | 
					
						
							| 
									
										
										
										
											2017-01-24 02:52:20 +08:00
										 |  |  | 				iterationOfArrayCallback(block.blocks, addDependenciesBlock); | 
					
						
							| 
									
										
										
										
											2013-01-31 01:49:25 +08:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2017-01-06 01:00:36 +08:00
										 |  |  | 			if(block.variables) { | 
					
						
							| 
									
										
										
										
											2017-01-24 02:52:20 +08:00
										 |  |  | 				iterationBlockVariable(block.variables, addDependency); | 
					
						
							| 
									
										
										
										
											2013-05-08 20:47:13 +08:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2017-11-08 18:32:05 +08:00
										 |  |  | 		}; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-19 16:06:40 +08:00
										 |  |  | 		try { | 
					
						
							|  |  |  | 			addDependenciesBlock(module); | 
					
						
							|  |  |  | 		} catch(e) { | 
					
						
							|  |  |  | 			callback(e); | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2017-11-19 07:22:38 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		const sortedDependencies = []; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		for(const pair1 of dependencies) { | 
					
						
							|  |  |  | 			for(const pair2 of pair1[1]) { | 
					
						
							|  |  |  | 				sortedDependencies.push({ | 
					
						
							|  |  |  | 					factory: pair1[0], | 
					
						
							|  |  |  | 					dependencies: pair2[1] | 
					
						
							|  |  |  | 				}); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		this.addModuleDependencies(module, sortedDependencies, this.bail, null, true, callback); | 
					
						
							| 
									
										
										
										
											2017-01-06 01:00:36 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2013-05-08 19:28:54 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-06 01:00:36 +08:00
										 |  |  | 	addModuleDependencies(module, dependencies, bail, cacheGroup, recursive, callback) { | 
					
						
							|  |  |  | 		let _this = this; | 
					
						
							| 
									
										
										
										
											2017-05-04 10:17:23 +08:00
										 |  |  | 		const start = _this.profile && Date.now(); | 
					
						
							| 
									
										
										
										
											2013-01-31 01:49:25 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-19 07:22:38 +08:00
										 |  |  | 		asyncLib.forEach(dependencies, (item, callback) => { | 
					
						
							|  |  |  | 			const dependencies = item.dependencies; | 
					
						
							| 
									
										
										
										
											2013-01-31 01:49:25 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-08 18:32:05 +08:00
										 |  |  | 			const errorAndCallback = err => { | 
					
						
							| 
									
										
										
										
											2017-01-06 01:00:36 +08:00
										 |  |  | 				err.origin = module; | 
					
						
							|  |  |  | 				_this.errors.push(err); | 
					
						
							|  |  |  | 				if(bail) { | 
					
						
							|  |  |  | 					callback(err); | 
					
						
							|  |  |  | 				} else { | 
					
						
							|  |  |  | 					callback(); | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			}; | 
					
						
							| 
									
										
										
										
											2017-11-08 18:32:05 +08:00
										 |  |  | 			const warningAndCallback = err => { | 
					
						
							| 
									
										
										
										
											2017-01-06 01:00:36 +08:00
										 |  |  | 				err.origin = module; | 
					
						
							|  |  |  | 				_this.warnings.push(err); | 
					
						
							|  |  |  | 				callback(); | 
					
						
							|  |  |  | 			}; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-10-11 18:26:31 +08:00
										 |  |  | 			const semaphore = _this.semaphore; | 
					
						
							|  |  |  | 			semaphore.acquire(() => { | 
					
						
							|  |  |  | 				if(_this === null) return semaphore.release(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-19 07:22:38 +08:00
										 |  |  | 				const factory = item.factory; | 
					
						
							| 
									
										
										
										
											2017-08-11 22:11:17 +08:00
										 |  |  | 				factory.create({ | 
					
						
							|  |  |  | 					contextInfo: { | 
					
						
							|  |  |  | 						issuer: module.nameForCondition && module.nameForCondition(), | 
					
						
							|  |  |  | 						compiler: _this.compiler.name | 
					
						
							|  |  |  | 					}, | 
					
						
							| 
									
										
										
										
											2017-11-17 21:26:23 +08:00
										 |  |  | 					resolveOptions: module.resolveOptions, | 
					
						
							| 
									
										
										
										
											2017-08-11 22:11:17 +08:00
										 |  |  | 					context: module.context, | 
					
						
							|  |  |  | 					dependencies: dependencies | 
					
						
							| 
									
										
										
										
											2017-11-08 18:32:05 +08:00
										 |  |  | 				}, (err, dependentModule) => { | 
					
						
							| 
									
										
										
										
											2017-10-11 18:26:31 +08:00
										 |  |  | 					if(_this === null) return semaphore.release(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-11 22:11:17 +08:00
										 |  |  | 					let afterFactory; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-08 18:32:05 +08:00
										 |  |  | 					const isOptional = () => { | 
					
						
							| 
									
										
										
										
											2017-11-06 20:02:35 +08:00
										 |  |  | 						return dependencies.every(d => d.optional); | 
					
						
							| 
									
										
										
										
											2017-11-08 18:32:05 +08:00
										 |  |  | 					}; | 
					
						
							| 
									
										
										
										
											2014-07-03 06:00:06 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-08 18:32:05 +08:00
										 |  |  | 					const errorOrWarningAndCallback = err => { | 
					
						
							| 
									
										
										
										
											2017-08-11 22:11:17 +08:00
										 |  |  | 						if(isOptional()) { | 
					
						
							|  |  |  | 							return warningAndCallback(err); | 
					
						
							|  |  |  | 						} else { | 
					
						
							|  |  |  | 							return errorAndCallback(err); | 
					
						
							|  |  |  | 						} | 
					
						
							| 
									
										
										
										
											2017-11-08 18:32:05 +08:00
										 |  |  | 					}; | 
					
						
							| 
									
										
										
										
											2017-01-24 02:52:20 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-08 18:32:05 +08:00
										 |  |  | 					const iterationDependencies = depend => { | 
					
						
							| 
									
										
										
										
											2017-08-11 22:11:17 +08:00
										 |  |  | 						for(let index = 0; index < depend.length; index++) { | 
					
						
							|  |  |  | 							const dep = depend[index]; | 
					
						
							|  |  |  | 							dep.module = dependentModule; | 
					
						
							|  |  |  | 							dependentModule.addReason(module, dep); | 
					
						
							|  |  |  | 						} | 
					
						
							| 
									
										
										
										
											2017-11-08 18:32:05 +08:00
										 |  |  | 					}; | 
					
						
							| 
									
										
										
										
											2017-01-24 02:52:20 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-11 22:11:17 +08:00
										 |  |  | 					if(err) { | 
					
						
							| 
									
										
										
										
											2017-10-11 18:26:31 +08:00
										 |  |  | 						semaphore.release(); | 
					
						
							| 
									
										
										
										
											2017-08-11 22:11:17 +08:00
										 |  |  | 						return errorOrWarningAndCallback(new ModuleNotFoundError(module, err, dependencies)); | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 					if(!dependentModule) { | 
					
						
							| 
									
										
										
										
											2017-10-11 18:26:31 +08:00
										 |  |  | 						semaphore.release(); | 
					
						
							| 
									
										
										
										
											2017-08-11 22:11:17 +08:00
										 |  |  | 						return process.nextTick(callback); | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 					if(_this.profile) { | 
					
						
							|  |  |  | 						if(!dependentModule.profile) { | 
					
						
							|  |  |  | 							dependentModule.profile = {}; | 
					
						
							|  |  |  | 						} | 
					
						
							|  |  |  | 						afterFactory = Date.now(); | 
					
						
							|  |  |  | 						dependentModule.profile.factory = afterFactory - start; | 
					
						
							| 
									
										
										
										
											2014-06-04 03:03:21 +08:00
										 |  |  | 					} | 
					
						
							| 
									
										
										
										
											2013-05-08 20:47:13 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-11 22:11:17 +08:00
										 |  |  | 					const newModule = _this.addModule(dependentModule, cacheGroup); | 
					
						
							| 
									
										
										
										
											2013-01-31 01:49:25 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-11 22:11:17 +08:00
										 |  |  | 					if(!newModule) { // from cache
 | 
					
						
							|  |  |  | 						dependentModule = _this.getModule(dependentModule); | 
					
						
							| 
									
										
										
										
											2013-05-08 20:47:13 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-11 22:11:17 +08:00
										 |  |  | 						iterationDependencies(dependencies); | 
					
						
							| 
									
										
										
										
											2013-01-31 01:49:25 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-11 22:11:17 +08:00
										 |  |  | 						if(_this.profile) { | 
					
						
							|  |  |  | 							if(!module.profile) { | 
					
						
							|  |  |  | 								module.profile = {}; | 
					
						
							|  |  |  | 							} | 
					
						
							|  |  |  | 							const time = Date.now() - start; | 
					
						
							|  |  |  | 							if(!module.profile.dependencies || time > module.profile.dependencies) { | 
					
						
							|  |  |  | 								module.profile.dependencies = time; | 
					
						
							|  |  |  | 							} | 
					
						
							| 
									
										
										
										
											2017-01-06 01:00:36 +08:00
										 |  |  | 						} | 
					
						
							| 
									
										
										
										
											2017-08-11 22:11:17 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-10-11 18:26:31 +08:00
										 |  |  | 						semaphore.release(); | 
					
						
							| 
									
										
										
										
											2017-11-06 20:02:35 +08:00
										 |  |  | 						_this.waitForBuildingFinished(dependentModule, callback); | 
					
						
							|  |  |  | 						return; | 
					
						
							| 
									
										
										
										
											2017-01-06 01:00:36 +08:00
										 |  |  | 					} | 
					
						
							| 
									
										
										
										
											2015-02-05 06:21:22 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-11 22:11:17 +08:00
										 |  |  | 					if(newModule instanceof Module) { | 
					
						
							|  |  |  | 						if(_this.profile) { | 
					
						
							|  |  |  | 							newModule.profile = dependentModule.profile; | 
					
						
							|  |  |  | 						} | 
					
						
							| 
									
										
										
										
											2013-05-08 19:28:54 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 20:02:35 +08:00
										 |  |  | 						newModule.issuer = module; | 
					
						
							| 
									
										
										
										
											2017-08-11 22:11:17 +08:00
										 |  |  | 						dependentModule = newModule; | 
					
						
							| 
									
										
										
										
											2014-07-03 06:00:06 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-11 22:11:17 +08:00
										 |  |  | 						iterationDependencies(dependencies); | 
					
						
							| 
									
										
										
										
											2013-05-18 20:42:11 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-11 22:11:17 +08:00
										 |  |  | 						if(_this.profile) { | 
					
						
							|  |  |  | 							const afterBuilding = Date.now(); | 
					
						
							|  |  |  | 							module.profile.building = afterBuilding - afterFactory; | 
					
						
							|  |  |  | 						} | 
					
						
							| 
									
										
										
										
											2013-01-31 01:49:25 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-10-11 18:26:31 +08:00
										 |  |  | 						semaphore.release(); | 
					
						
							| 
									
										
										
										
											2017-08-11 22:11:17 +08:00
										 |  |  | 						if(recursive) { | 
					
						
							|  |  |  | 							return process.nextTick(_this.processModuleDependencies.bind(_this, dependentModule, callback)); | 
					
						
							|  |  |  | 						} else { | 
					
						
							|  |  |  | 							return process.nextTick(callback); | 
					
						
							|  |  |  | 						} | 
					
						
							| 
									
										
										
										
											2017-01-06 01:00:36 +08:00
										 |  |  | 					} | 
					
						
							| 
									
										
										
										
											2013-05-08 20:47:13 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 20:02:35 +08:00
										 |  |  | 					dependentModule.issuer = module; | 
					
						
							| 
									
										
										
										
											2013-01-31 01:49:25 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-11 22:11:17 +08:00
										 |  |  | 					iterationDependencies(dependencies); | 
					
						
							| 
									
										
										
										
											2013-01-31 01:49:25 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-11 22:11:17 +08:00
										 |  |  | 					_this.buildModule(dependentModule, isOptional(), module, dependencies, err => { | 
					
						
							| 
									
										
										
										
											2017-10-11 18:26:31 +08:00
										 |  |  | 						if(_this === null) return semaphore.release(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-11 22:11:17 +08:00
										 |  |  | 						if(err) { | 
					
						
							| 
									
										
										
										
											2017-10-11 18:26:31 +08:00
										 |  |  | 							semaphore.release(); | 
					
						
							| 
									
										
										
										
											2017-08-11 22:11:17 +08:00
										 |  |  | 							return errorOrWarningAndCallback(err); | 
					
						
							|  |  |  | 						} | 
					
						
							| 
									
										
										
										
											2013-01-31 01:49:25 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-11 22:11:17 +08:00
										 |  |  | 						if(_this.profile) { | 
					
						
							|  |  |  | 							const afterBuilding = Date.now(); | 
					
						
							|  |  |  | 							dependentModule.profile.building = afterBuilding - afterFactory; | 
					
						
							|  |  |  | 						} | 
					
						
							| 
									
										
										
										
											2015-02-05 06:21:22 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-10-11 18:26:31 +08:00
										 |  |  | 						semaphore.release(); | 
					
						
							| 
									
										
										
										
											2017-08-11 22:11:17 +08:00
										 |  |  | 						if(recursive) { | 
					
						
							|  |  |  | 							_this.processModuleDependencies(dependentModule, callback); | 
					
						
							|  |  |  | 						} else { | 
					
						
							|  |  |  | 							return callback(); | 
					
						
							|  |  |  | 						} | 
					
						
							|  |  |  | 					}); | 
					
						
							| 
									
										
										
										
											2013-01-31 01:49:25 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-06 01:00:36 +08:00
										 |  |  | 				}); | 
					
						
							|  |  |  | 			}); | 
					
						
							| 
									
										
										
										
											2017-11-08 18:32:05 +08:00
										 |  |  | 		}, err => { | 
					
						
							| 
									
										
										
										
											2017-01-06 01:00:36 +08:00
										 |  |  | 			// In V8, the Error objects keep a reference to the functions on the stack. These warnings &
 | 
					
						
							|  |  |  | 			// errors are created inside closures that keep a reference to the Compilation, so errors are
 | 
					
						
							|  |  |  | 			// leaking the Compilation object. Setting _this to null workarounds the following issue in V8.
 | 
					
						
							|  |  |  | 			// https://bugs.chromium.org/p/chromium/issues/detail?id=612191
 | 
					
						
							|  |  |  | 			_this = null; | 
					
						
							| 
									
										
										
										
											2013-01-31 01:49:25 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-06 01:00:36 +08:00
										 |  |  | 			if(err) { | 
					
						
							|  |  |  | 				return callback(err); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			return process.nextTick(callback); | 
					
						
							|  |  |  | 		}); | 
					
						
							| 
									
										
										
										
											2014-06-04 03:03:21 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2013-01-31 01:49:25 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-06 01:00:36 +08:00
										 |  |  | 	_addModuleChain(context, dependency, onModule, callback) { | 
					
						
							| 
									
										
										
										
											2017-05-04 10:17:23 +08:00
										 |  |  | 		const start = this.profile && Date.now(); | 
					
						
							| 
									
										
										
										
											2017-01-06 01:00:36 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-11 11:58:49 +08:00
										 |  |  | 		const errorAndCallback = this.bail ? (err) => { | 
					
						
							| 
									
										
										
										
											2017-01-06 01:00:36 +08:00
										 |  |  | 			callback(err); | 
					
						
							| 
									
										
										
										
											2017-08-11 11:58:49 +08:00
										 |  |  | 		} : (err) => { | 
					
						
							| 
									
										
										
										
											2017-01-06 01:00:36 +08:00
										 |  |  | 			err.dependencies = [dependency]; | 
					
						
							|  |  |  | 			this.errors.push(err); | 
					
						
							|  |  |  | 			callback(); | 
					
						
							| 
									
										
										
										
											2017-08-11 12:05:25 +08:00
										 |  |  | 		}; | 
					
						
							| 
									
										
										
										
											2017-01-06 01:00:36 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		if(typeof dependency !== "object" || dependency === null || !dependency.constructor) { | 
					
						
							|  |  |  | 			throw new Error("Parameter 'dependency' must be a Dependency"); | 
					
						
							| 
									
										
										
										
											2014-06-04 03:03:21 +08:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2013-01-31 01:49:25 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-06 01:00:36 +08:00
										 |  |  | 		const moduleFactory = this.dependencyFactories.get(dependency.constructor); | 
					
						
							|  |  |  | 		if(!moduleFactory) { | 
					
						
							|  |  |  | 			throw new Error(`No dependency factory available for this dependency type: ${dependency.constructor.name}`); | 
					
						
							| 
									
										
										
										
											2013-05-13 19:34:00 +08:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-11 22:11:17 +08:00
										 |  |  | 		this.semaphore.acquire(() => { | 
					
						
							|  |  |  | 			moduleFactory.create({ | 
					
						
							|  |  |  | 				contextInfo: { | 
					
						
							|  |  |  | 					issuer: "", | 
					
						
							|  |  |  | 					compiler: this.compiler.name | 
					
						
							|  |  |  | 				}, | 
					
						
							|  |  |  | 				context: context, | 
					
						
							|  |  |  | 				dependencies: [dependency] | 
					
						
							|  |  |  | 			}, (err, module) => { | 
					
						
							|  |  |  | 				if(err) { | 
					
						
							|  |  |  | 					this.semaphore.release(); | 
					
						
							|  |  |  | 					return errorAndCallback(new EntryModuleNotFoundError(err)); | 
					
						
							| 
									
										
										
										
											2017-01-06 01:00:36 +08:00
										 |  |  | 				} | 
					
						
							| 
									
										
										
										
											2013-05-08 19:28:54 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-11 22:11:17 +08:00
										 |  |  | 				let afterFactory; | 
					
						
							| 
									
										
										
										
											2017-01-06 01:00:36 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 				if(this.profile) { | 
					
						
							| 
									
										
										
										
											2017-08-11 22:11:17 +08:00
										 |  |  | 					if(!module.profile) { | 
					
						
							|  |  |  | 						module.profile = {}; | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 					afterFactory = Date.now(); | 
					
						
							|  |  |  | 					module.profile.factory = afterFactory - start; | 
					
						
							| 
									
										
										
										
											2017-01-06 01:00:36 +08:00
										 |  |  | 				} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-11 22:11:17 +08:00
										 |  |  | 				const result = this.addModule(module); | 
					
						
							|  |  |  | 				if(!result) { | 
					
						
							|  |  |  | 					module = this.getModule(module); | 
					
						
							| 
									
										
										
										
											2013-05-13 19:34:00 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-11 22:11:17 +08:00
										 |  |  | 					onModule(module); | 
					
						
							| 
									
										
										
										
											2017-01-06 01:00:36 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 20:02:35 +08:00
										 |  |  | 					dependency.module = module; | 
					
						
							|  |  |  | 					module.addReason(null, dependency); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-11 22:11:17 +08:00
										 |  |  | 					if(this.profile) { | 
					
						
							|  |  |  | 						const afterBuilding = Date.now(); | 
					
						
							|  |  |  | 						module.profile.building = afterBuilding - afterFactory; | 
					
						
							|  |  |  | 					} | 
					
						
							| 
									
										
										
										
											2017-01-06 01:00:36 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-11 22:11:17 +08:00
										 |  |  | 					this.semaphore.release(); | 
					
						
							| 
									
										
										
										
											2017-11-06 20:02:35 +08:00
										 |  |  | 					this.waitForBuildingFinished(module, err => { | 
					
						
							|  |  |  | 						if(err) return callback(err); | 
					
						
							|  |  |  | 						callback(null, module); | 
					
						
							|  |  |  | 					}); | 
					
						
							|  |  |  | 					return; | 
					
						
							| 
									
										
										
										
											2017-08-11 22:11:17 +08:00
										 |  |  | 				} | 
					
						
							| 
									
										
										
										
											2017-01-06 01:00:36 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-08 18:32:05 +08:00
										 |  |  | 				const moduleReady = () => { | 
					
						
							|  |  |  | 					this.semaphore.release(); | 
					
						
							|  |  |  | 					this.processModuleDependencies(module, err => { | 
					
						
							|  |  |  | 						if(err) { | 
					
						
							|  |  |  | 							return callback(err); | 
					
						
							|  |  |  | 						} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 						return callback(null, module); | 
					
						
							|  |  |  | 					}); | 
					
						
							|  |  |  | 				}; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-11 22:11:17 +08:00
										 |  |  | 				if(result instanceof Module) { | 
					
						
							|  |  |  | 					if(this.profile) { | 
					
						
							|  |  |  | 						result.profile = module.profile; | 
					
						
							|  |  |  | 					} | 
					
						
							| 
									
										
										
										
											2015-05-11 00:43:47 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-11 22:11:17 +08:00
										 |  |  | 					module = result; | 
					
						
							| 
									
										
										
										
											2015-05-11 00:43:47 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-11 22:11:17 +08:00
										 |  |  | 					onModule(module); | 
					
						
							| 
									
										
										
										
											2017-01-06 01:00:36 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 20:02:35 +08:00
										 |  |  | 					dependency.module = module; | 
					
						
							|  |  |  | 					module.addReason(null, dependency); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-08 18:32:05 +08:00
										 |  |  | 					moduleReady(); | 
					
						
							| 
									
										
										
										
											2017-08-11 22:11:17 +08:00
										 |  |  | 					return; | 
					
						
							| 
									
										
										
										
											2017-01-06 01:00:36 +08:00
										 |  |  | 				} | 
					
						
							| 
									
										
										
										
											2013-01-31 01:49:25 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-11 22:11:17 +08:00
										 |  |  | 				onModule(module); | 
					
						
							| 
									
										
										
										
											2017-01-06 01:00:36 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 20:02:35 +08:00
										 |  |  | 				dependency.module = module; | 
					
						
							|  |  |  | 				module.addReason(null, dependency); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-08 18:32:05 +08:00
										 |  |  | 				this.buildModule(module, false, null, null, err => { | 
					
						
							| 
									
										
										
										
											2017-01-06 01:00:36 +08:00
										 |  |  | 					if(err) { | 
					
						
							| 
									
										
										
										
											2017-08-11 22:11:17 +08:00
										 |  |  | 						this.semaphore.release(); | 
					
						
							|  |  |  | 						return errorAndCallback(err); | 
					
						
							| 
									
										
										
										
											2017-01-06 01:00:36 +08:00
										 |  |  | 					} | 
					
						
							| 
									
										
										
										
											2013-01-31 01:49:25 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-11 22:11:17 +08:00
										 |  |  | 					if(this.profile) { | 
					
						
							|  |  |  | 						const afterBuilding = Date.now(); | 
					
						
							|  |  |  | 						module.profile.building = afterBuilding - afterFactory; | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-08 18:32:05 +08:00
										 |  |  | 					moduleReady(); | 
					
						
							| 
									
										
										
										
											2017-01-06 01:00:36 +08:00
										 |  |  | 				}); | 
					
						
							| 
									
										
										
										
											2017-08-11 22:11:17 +08:00
										 |  |  | 			}); | 
					
						
							| 
									
										
										
										
											2017-01-06 01:00:36 +08:00
										 |  |  | 		}); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	addEntry(context, entry, name, callback) { | 
					
						
							|  |  |  | 		const slot = { | 
					
						
							|  |  |  | 			name: name, | 
					
						
							|  |  |  | 			module: null | 
					
						
							|  |  |  | 		}; | 
					
						
							|  |  |  | 		this.preparedChunks.push(slot); | 
					
						
							|  |  |  | 		this._addModuleChain(context, entry, (module) => { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			this.entries.push(module); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		}, (err, module) => { | 
					
						
							| 
									
										
										
										
											2015-05-11 00:43:47 +08:00
										 |  |  | 			if(err) { | 
					
						
							| 
									
										
										
										
											2017-01-06 01:00:36 +08:00
										 |  |  | 				return callback(err); | 
					
						
							| 
									
										
										
										
											2015-05-11 00:43:47 +08:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2013-01-31 01:49:25 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-06 01:00:36 +08:00
										 |  |  | 			if(module) { | 
					
						
							|  |  |  | 				slot.module = module; | 
					
						
							|  |  |  | 			} else { | 
					
						
							|  |  |  | 				const idx = this.preparedChunks.indexOf(slot); | 
					
						
							|  |  |  | 				this.preparedChunks.splice(idx, 1); | 
					
						
							| 
									
										
										
										
											2015-05-11 00:43:47 +08:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2017-03-31 06:05:27 +08:00
										 |  |  | 			return callback(null, module); | 
					
						
							| 
									
										
										
										
											2017-01-06 01:00:36 +08:00
										 |  |  | 		}); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2013-05-13 19:34:00 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-06 01:00:36 +08:00
										 |  |  | 	prefetch(context, dependency, callback) { | 
					
						
							|  |  |  | 		this._addModuleChain(context, dependency, module => { | 
					
						
							| 
									
										
										
										
											2013-05-08 19:28:54 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-06 01:00:36 +08:00
										 |  |  | 			module.prefetched = true; | 
					
						
							| 
									
										
										
										
											2013-01-31 01:49:25 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-06 01:00:36 +08:00
										 |  |  | 		}, callback); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	rebuildModule(module, thisCallback) { | 
					
						
							| 
									
										
										
										
											2017-11-06 20:02:35 +08:00
										 |  |  | 		let callbackList = this._rebuildingModules.get(module); | 
					
						
							|  |  |  | 		if(callbackList) { | 
					
						
							|  |  |  | 			callbackList.push(thisCallback); | 
					
						
							|  |  |  | 			return; | 
					
						
							| 
									
										
										
										
											2014-06-04 03:03:21 +08:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2017-11-06 20:02:35 +08:00
										 |  |  | 		this._rebuildingModules.set(module, callbackList = [thisCallback]); | 
					
						
							| 
									
										
										
										
											2013-05-13 19:34:00 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 20:02:35 +08:00
										 |  |  | 		const callback = err => { | 
					
						
							|  |  |  | 			this._rebuildingModules.delete(module); | 
					
						
							|  |  |  | 			callbackList.forEach(cb => cb(err)); | 
					
						
							|  |  |  | 		}; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		const oldDependencies = module.dependencies.slice(); | 
					
						
							|  |  |  | 		const oldVariables = module.variables.slice(); | 
					
						
							|  |  |  | 		const oldBlocks = module.blocks.slice(); | 
					
						
							| 
									
										
										
										
											2017-01-06 01:00:36 +08:00
										 |  |  | 		this.buildModule(module, false, module, null, (err) => { | 
					
						
							|  |  |  | 			if(err) return callback(err); | 
					
						
							| 
									
										
										
										
											2013-05-13 19:34:00 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-06 01:00:36 +08:00
										 |  |  | 			this.processModuleDependencies(module, (err) => { | 
					
						
							|  |  |  | 				if(err) return callback(err); | 
					
						
							| 
									
										
										
										
											2017-11-06 20:02:35 +08:00
										 |  |  | 				this.removeReasonsOfDependencyBlock(module, { | 
					
						
							|  |  |  | 					dependencies: oldDependencies, | 
					
						
							|  |  |  | 					variables: oldVariables, | 
					
						
							|  |  |  | 					blocks: oldBlocks | 
					
						
							| 
									
										
										
										
											2017-01-06 01:00:36 +08:00
										 |  |  | 				}); | 
					
						
							|  |  |  | 				callback(); | 
					
						
							|  |  |  | 			}); | 
					
						
							| 
									
										
										
										
											2013-05-13 19:34:00 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-06 01:00:36 +08:00
										 |  |  | 		}); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2013-05-13 19:34:00 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-06 01:00:36 +08:00
										 |  |  | 	finish() { | 
					
						
							| 
									
										
										
										
											2017-03-02 22:09:09 +08:00
										 |  |  | 		const modules = this.modules; | 
					
						
							| 
									
										
										
										
											2017-11-27 22:27:30 +08:00
										 |  |  | 		this.hooks.finishModules.call(modules); | 
					
						
							| 
									
										
										
										
											2017-01-24 02:52:20 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-02 22:09:09 +08:00
										 |  |  | 		for(let index = 0; index < modules.length; index++) { | 
					
						
							|  |  |  | 			const module = modules[index]; | 
					
						
							| 
									
										
										
										
											2017-01-24 02:52:20 +08:00
										 |  |  | 			this.reportDependencyErrorsAndWarnings(module, [module]); | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2017-01-06 01:00:36 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2013-05-13 19:34:00 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-06 01:00:36 +08:00
										 |  |  | 	unseal() { | 
					
						
							| 
									
										
										
										
											2017-11-27 22:27:30 +08:00
										 |  |  | 		this.hooks.unseal.call(); | 
					
						
							| 
									
										
										
										
											2017-01-06 01:00:36 +08:00
										 |  |  | 		this.chunks.length = 0; | 
					
						
							|  |  |  | 		this.namedChunks = {}; | 
					
						
							|  |  |  | 		this.additionalChunkAssets.length = 0; | 
					
						
							|  |  |  | 		this.assets = {}; | 
					
						
							|  |  |  | 		this.modules.forEach(module => module.unseal()); | 
					
						
							| 
									
										
										
										
											2014-07-29 06:13:25 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-07-08 20:15:21 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-06 01:00:36 +08:00
										 |  |  | 	seal(callback) { | 
					
						
							| 
									
										
										
										
											2017-11-27 22:27:30 +08:00
										 |  |  | 		this.hooks.seal.call(); | 
					
						
							| 
									
										
										
										
											2017-08-08 15:40:17 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-27 22:27:30 +08:00
										 |  |  | 		while(this.hooks.optimizeDependenciesBasic.call(this.modules) || | 
					
						
							|  |  |  | 			this.hooks.optimizeDependencies.call(this.modules) || | 
					
						
							|  |  |  | 			this.hooks.optimizeDependenciesAdvanced.call(this.modules)) { /* empty */ } | 
					
						
							|  |  |  | 		this.hooks.afterOptimizeDependencies.call(this.modules); | 
					
						
							| 
									
										
										
										
											2017-08-08 15:40:17 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-08 18:32:05 +08:00
										 |  |  | 		this.nextFreeModuleIndex = 0; | 
					
						
							|  |  |  | 		this.nextFreeModuleIndex2 = 0; | 
					
						
							|  |  |  | 		this.preparedChunks.forEach(preparedChunk => { | 
					
						
							| 
									
										
										
										
											2017-01-06 01:00:36 +08:00
										 |  |  | 			const module = preparedChunk.module; | 
					
						
							| 
									
										
										
										
											2017-11-08 18:32:05 +08:00
										 |  |  | 			const chunk = this.addChunk(preparedChunk.name, module); | 
					
						
							|  |  |  | 			const entrypoint = this.entrypoints[chunk.name] = new Entrypoint(chunk.name); | 
					
						
							| 
									
										
										
										
											2017-01-06 01:00:36 +08:00
										 |  |  | 			entrypoint.unshiftChunk(chunk); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			chunk.addModule(module); | 
					
						
							|  |  |  | 			module.addChunk(chunk); | 
					
						
							|  |  |  | 			chunk.entryModule = module; | 
					
						
							| 
									
										
										
										
											2017-11-08 18:32:05 +08:00
										 |  |  | 			this.assignIndex(module); | 
					
						
							|  |  |  | 			this.assignDepth(module); | 
					
						
							| 
									
										
										
										
											2014-07-29 06:13:25 +08:00
										 |  |  | 		}); | 
					
						
							| 
									
										
										
										
											2017-11-08 18:32:05 +08:00
										 |  |  | 		this.processDependenciesBlocksForChunks(this.chunks.slice()); | 
					
						
							|  |  |  | 		this.sortModules(this.modules); | 
					
						
							| 
									
										
										
										
											2017-11-27 22:27:30 +08:00
										 |  |  | 		this.hooks.optimize.call(); | 
					
						
							| 
									
										
										
										
											2014-07-19 20:32:48 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-27 22:27:30 +08:00
										 |  |  | 		while(this.hooks.optimizeModulesBasic.call(this.modules) || | 
					
						
							|  |  |  | 			this.hooks.optimizeModules.call(this.modules) || | 
					
						
							|  |  |  | 			this.hooks.optimizeModulesAdvanced.call(this.modules)) { /* empty */ } | 
					
						
							|  |  |  | 		this.hooks.afterOptimizeModules.call(this.modules); | 
					
						
							| 
									
										
										
										
											2014-01-29 17:13:28 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-27 22:27:30 +08:00
										 |  |  | 		while(this.hooks.optimizeChunksBasic.call(this.chunks) || | 
					
						
							|  |  |  | 			this.hooks.optimizeChunks.call(this.chunks) || | 
					
						
							|  |  |  | 			this.hooks.optimizeChunksAdvanced.call(this.chunks)) { /* empty */ } | 
					
						
							|  |  |  | 		this.hooks.afterOptimizeChunks.call(this.chunks); | 
					
						
							| 
									
										
										
										
											2015-04-21 01:39:02 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-27 22:27:30 +08:00
										 |  |  | 		this.hooks.optimizeTree.callAsync(this.chunks, this.modules, err => { | 
					
						
							| 
									
										
										
										
											2017-01-06 01:00:36 +08:00
										 |  |  | 			if(err) { | 
					
						
							|  |  |  | 				return callback(err); | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2014-09-03 20:16:17 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-27 22:27:30 +08:00
										 |  |  | 			this.hooks.afterOptimizeTree.call(this.chunks, this.modules); | 
					
						
							| 
									
										
										
										
											2016-07-13 17:03:14 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-27 22:27:30 +08:00
										 |  |  | 			while(this.hooks.optimizeChunkModulesBasic.call(this.chunks, this.modules) || | 
					
						
							|  |  |  | 				this.hooks.optimizeChunkModules.call(this.chunks, this.modules) || | 
					
						
							|  |  |  | 				this.hooks.optimizeChunkModulesAdvanced.call(this.chunks, this.modules)) { /* empty */ } | 
					
						
							|  |  |  | 			this.hooks.afterOptimizeChunkModules.call(this.chunks, this.modules); | 
					
						
							| 
									
										
										
										
											2017-05-10 19:15:14 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-27 22:27:30 +08:00
										 |  |  | 			const shouldRecord = this.hooks.shouldRecord.call() !== false; | 
					
						
							| 
									
										
										
										
											2016-07-13 17:03:14 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-27 22:27:30 +08:00
										 |  |  | 			this.hooks.reviveModules.call(this.modules, this.records); | 
					
						
							|  |  |  | 			this.hooks.optimizeModuleOrder.call(this.modules); | 
					
						
							|  |  |  | 			this.hooks.advancedOptimizeModuleOrder.call(this.modules); | 
					
						
							|  |  |  | 			this.hooks.beforeModuleIds.call(this.modules); | 
					
						
							|  |  |  | 			this.hooks.moduleIds.call(this.modules); | 
					
						
							| 
									
										
										
										
											2017-11-08 18:32:05 +08:00
										 |  |  | 			this.applyModuleIds(); | 
					
						
							| 
									
										
										
										
											2017-11-27 22:27:30 +08:00
										 |  |  | 			this.hooks.optimizeModuleIds.call(this.modules); | 
					
						
							|  |  |  | 			this.hooks.afterOptimizeModuleIds.call(this.modules); | 
					
						
							| 
									
										
										
										
											2016-07-13 17:03:14 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-08 18:32:05 +08:00
										 |  |  | 			this.sortItemsWithModuleIds(); | 
					
						
							| 
									
										
										
										
											2016-07-13 17:03:14 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-27 22:27:30 +08:00
										 |  |  | 			this.hooks.reviveChunks.call(this.chunks, this.records); | 
					
						
							|  |  |  | 			this.hooks.optimizeChunkOrder.call(this.chunks); | 
					
						
							|  |  |  | 			this.hooks.beforeChunkIds.call(this.chunks); | 
					
						
							| 
									
										
										
										
											2017-11-08 18:32:05 +08:00
										 |  |  | 			this.applyChunkIds(); | 
					
						
							| 
									
										
										
										
											2017-11-27 22:27:30 +08:00
										 |  |  | 			this.hooks.optimizeChunkIds.call(this.chunks); | 
					
						
							|  |  |  | 			this.hooks.afterOptimizeChunkIds.call(this.chunks); | 
					
						
							| 
									
										
										
										
											2014-01-29 17:13:28 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-08 18:32:05 +08:00
										 |  |  | 			this.sortItemsWithChunkIds(); | 
					
						
							| 
									
										
										
										
											2016-07-13 17:03:14 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-06 01:00:36 +08:00
										 |  |  | 			if(shouldRecord) | 
					
						
							| 
									
										
										
										
											2017-11-27 22:27:30 +08:00
										 |  |  | 				this.hooks.recordModules.call(this.modules, this.records); | 
					
						
							| 
									
										
										
										
											2017-01-06 01:00:36 +08:00
										 |  |  | 			if(shouldRecord) | 
					
						
							| 
									
										
										
										
											2017-11-27 22:27:30 +08:00
										 |  |  | 				this.hooks.recordChunks.call(this.chunks, this.records); | 
					
						
							| 
									
										
										
										
											2016-07-13 17:03:14 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-27 22:27:30 +08:00
										 |  |  | 			this.hooks.beforeHash.call(); | 
					
						
							| 
									
										
										
										
											2017-11-08 18:32:05 +08:00
										 |  |  | 			this.createHash(); | 
					
						
							| 
									
										
										
										
											2017-11-27 22:27:30 +08:00
										 |  |  | 			this.hooks.afterHash.call(); | 
					
						
							| 
									
										
										
										
											2014-01-29 17:13:28 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-06 01:00:36 +08:00
										 |  |  | 			if(shouldRecord) | 
					
						
							| 
									
										
										
										
											2017-11-27 22:27:30 +08:00
										 |  |  | 				this.hooks.recordHash.call(this.records); | 
					
						
							| 
									
										
										
										
											2017-01-06 01:00:36 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-27 22:27:30 +08:00
										 |  |  | 			this.hooks.beforeModuleAssets.call(); | 
					
						
							| 
									
										
										
										
											2017-11-08 18:32:05 +08:00
										 |  |  | 			this.createModuleAssets(); | 
					
						
							| 
									
										
										
										
											2017-11-27 22:27:30 +08:00
										 |  |  | 			if(this.hooks.shouldGenerateChunkAssets.call() !== false) { | 
					
						
							|  |  |  | 				this.hooks.beforeChunkAssets.call(); | 
					
						
							| 
									
										
										
										
											2017-11-08 18:32:05 +08:00
										 |  |  | 				this.createChunkAssets(); | 
					
						
							| 
									
										
										
										
											2014-06-04 03:03:21 +08:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2017-11-27 22:27:30 +08:00
										 |  |  | 			this.hooks.additionalChunkAssets.call(this.chunks); | 
					
						
							| 
									
										
										
										
											2017-11-08 18:32:05 +08:00
										 |  |  | 			this.summarizeDependencies(); | 
					
						
							| 
									
										
										
										
											2017-01-06 01:00:36 +08:00
										 |  |  | 			if(shouldRecord) | 
					
						
							| 
									
										
										
										
											2017-11-27 22:27:30 +08:00
										 |  |  | 				this.hooks.record.call(this, this.records); | 
					
						
							| 
									
										
										
										
											2017-01-06 01:00:36 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-27 22:27:30 +08:00
										 |  |  | 			this.hooks.additionalAssets.callAsync(err => { | 
					
						
							| 
									
										
										
										
											2014-06-04 03:03:21 +08:00
										 |  |  | 				if(err) { | 
					
						
							|  |  |  | 					return callback(err); | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2017-11-27 22:27:30 +08:00
										 |  |  | 				this.hooks.optimizeChunkAssets.callAsync(this.chunks, err => { | 
					
						
							| 
									
										
										
										
											2014-06-04 03:03:21 +08:00
										 |  |  | 					if(err) { | 
					
						
							|  |  |  | 						return callback(err); | 
					
						
							|  |  |  | 					} | 
					
						
							| 
									
										
										
										
											2017-11-27 22:27:30 +08:00
										 |  |  | 					this.hooks.afterOptimizeChunkAssets.call(this.chunks); | 
					
						
							|  |  |  | 					this.hooks.optimizeAssets.callAsync(this.assets, err => { | 
					
						
							| 
									
										
										
										
											2017-01-06 01:00:36 +08:00
										 |  |  | 						if(err) { | 
					
						
							|  |  |  | 							return callback(err); | 
					
						
							|  |  |  | 						} | 
					
						
							| 
									
										
										
										
											2017-11-27 22:27:30 +08:00
										 |  |  | 						this.hooks.afterOptimizeAssets.call(this.assets); | 
					
						
							|  |  |  | 						if(this.hooks.needAdditionalSeal.call()) { | 
					
						
							| 
									
										
										
										
											2017-11-08 18:32:05 +08:00
										 |  |  | 							this.unseal(); | 
					
						
							|  |  |  | 							return this.seal(callback); | 
					
						
							| 
									
										
										
										
											2017-01-06 01:00:36 +08:00
										 |  |  | 						} | 
					
						
							| 
									
										
										
										
											2017-11-27 22:27:30 +08:00
										 |  |  | 						return this.hooks.afterSeal.callAsync(callback); | 
					
						
							| 
									
										
										
										
											2017-01-06 01:00:36 +08:00
										 |  |  | 					}); | 
					
						
							| 
									
										
										
										
											2016-10-18 02:26:22 +08:00
										 |  |  | 				}); | 
					
						
							|  |  |  | 			}); | 
					
						
							|  |  |  | 		}); | 
					
						
							| 
									
										
										
										
											2017-01-06 01:00:36 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	sortModules(modules) { | 
					
						
							|  |  |  | 		modules.sort((a, b) => { | 
					
						
							|  |  |  | 			if(a.index < b.index) return -1; | 
					
						
							|  |  |  | 			if(a.index > b.index) return 1; | 
					
						
							|  |  |  | 			return 0; | 
					
						
							| 
									
										
										
										
											2016-06-24 07:51:52 +08:00
										 |  |  | 		}); | 
					
						
							| 
									
										
										
										
											2017-01-06 01:00:36 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-10 00:11:34 +08:00
										 |  |  | 	reportDependencyErrorsAndWarnings(module, blocks) { | 
					
						
							| 
									
										
										
										
											2017-03-02 22:09:09 +08:00
										 |  |  | 		for(let indexBlock = 0; indexBlock < blocks.length; indexBlock++) { | 
					
						
							|  |  |  | 			const block = blocks[indexBlock]; | 
					
						
							|  |  |  | 			const dependencies = block.dependencies; | 
					
						
							| 
									
										
										
										
											2017-01-24 02:52:20 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-02 22:09:09 +08:00
										 |  |  | 			for(let indexDep = 0; indexDep < dependencies.length; indexDep++) { | 
					
						
							|  |  |  | 				const d = dependencies[indexDep]; | 
					
						
							| 
									
										
										
										
											2017-01-24 02:52:20 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-06 01:00:36 +08:00
										 |  |  | 				const warnings = d.getWarnings(); | 
					
						
							|  |  |  | 				if(warnings) { | 
					
						
							| 
									
										
										
										
											2017-03-02 22:09:09 +08:00
										 |  |  | 					for(let indexWar = 0; indexWar < warnings.length; indexWar++) { | 
					
						
							|  |  |  | 						const w = warnings[indexWar]; | 
					
						
							| 
									
										
										
										
											2017-01-24 02:52:20 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-02 22:09:09 +08:00
										 |  |  | 						const warning = new ModuleDependencyWarning(module, w, d.loc); | 
					
						
							| 
									
										
										
										
											2017-01-06 01:00:36 +08:00
										 |  |  | 						this.warnings.push(warning); | 
					
						
							| 
									
										
										
										
											2017-01-24 02:52:20 +08:00
										 |  |  | 					} | 
					
						
							| 
									
										
										
										
											2017-01-06 01:00:36 +08:00
										 |  |  | 				} | 
					
						
							| 
									
										
										
										
											2017-01-10 00:11:34 +08:00
										 |  |  | 				const errors = d.getErrors(); | 
					
						
							|  |  |  | 				if(errors) { | 
					
						
							| 
									
										
										
										
											2017-03-02 22:09:09 +08:00
										 |  |  | 					for(let indexErr = 0; indexErr < errors.length; indexErr++) { | 
					
						
							|  |  |  | 						const e = errors[indexErr]; | 
					
						
							| 
									
										
										
										
											2017-01-24 02:52:20 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-02 22:09:09 +08:00
										 |  |  | 						const error = new ModuleDependencyError(module, e, d.loc); | 
					
						
							| 
									
										
										
										
											2017-01-24 02:52:20 +08:00
										 |  |  | 						this.errors.push(error); | 
					
						
							|  |  |  | 					} | 
					
						
							| 
									
										
										
										
											2017-01-10 00:11:34 +08:00
										 |  |  | 				} | 
					
						
							| 
									
										
										
										
											2017-01-24 02:52:20 +08:00
										 |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-10 00:11:34 +08:00
										 |  |  | 			this.reportDependencyErrorsAndWarnings(module, block.blocks); | 
					
						
							| 
									
										
										
										
											2017-01-24 02:52:20 +08:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2017-01-06 01:00:36 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	addChunk(name, module, loc) { | 
					
						
							|  |  |  | 		if(name) { | 
					
						
							|  |  |  | 			if(Object.prototype.hasOwnProperty.call(this.namedChunks, name)) { | 
					
						
							| 
									
										
										
										
											2017-02-05 08:18:40 +08:00
										 |  |  | 				const chunk = this.namedChunks[name]; | 
					
						
							| 
									
										
										
										
											2017-01-06 01:00:36 +08:00
										 |  |  | 				if(module) { | 
					
						
							|  |  |  | 					chunk.addOrigin(module, loc); | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				return chunk; | 
					
						
							| 
									
										
										
										
											2014-06-04 03:03:21 +08:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2014-01-24 20:32:58 +08:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2017-02-05 08:18:40 +08:00
										 |  |  | 		const chunk = new Chunk(name, module, loc); | 
					
						
							| 
									
										
										
										
											2017-01-06 01:00:36 +08:00
										 |  |  | 		this.chunks.push(chunk); | 
					
						
							|  |  |  | 		if(name) { | 
					
						
							|  |  |  | 			this.namedChunks[name] = chunk; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		return chunk; | 
					
						
							| 
									
										
										
										
											2013-01-31 01:49:25 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-06 01:00:36 +08:00
										 |  |  | 	assignIndex(module) { | 
					
						
							|  |  |  | 		const _this = this; | 
					
						
							| 
									
										
										
										
											2016-12-05 06:47:19 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-08 18:32:05 +08:00
										 |  |  | 		const assignIndexToModule = module => { | 
					
						
							| 
									
										
										
										
											2017-01-06 01:00:36 +08:00
										 |  |  | 			// enter module
 | 
					
						
							|  |  |  | 			if(typeof module.index !== "number") { | 
					
						
							|  |  |  | 				module.index = _this.nextFreeModuleIndex++; | 
					
						
							| 
									
										
										
										
											2016-12-05 06:47:19 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 				// leave module
 | 
					
						
							| 
									
										
										
										
											2017-01-06 01:00:36 +08:00
										 |  |  | 				queue.push(() => module.index2 = _this.nextFreeModuleIndex2++); | 
					
						
							| 
									
										
										
										
											2016-12-05 06:47:19 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-06 01:00:36 +08:00
										 |  |  | 				// enter it as block
 | 
					
						
							|  |  |  | 				assignIndexToDependencyBlock(module); | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2017-11-08 18:32:05 +08:00
										 |  |  | 		}; | 
					
						
							| 
									
										
										
										
											2016-12-05 06:47:19 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-08 18:32:05 +08:00
										 |  |  | 		const assignIndexToDependency = dependency => { | 
					
						
							| 
									
										
										
										
											2017-01-06 01:00:36 +08:00
										 |  |  | 			if(dependency.module) { | 
					
						
							|  |  |  | 				queue.push(() => assignIndexToModule(dependency.module)); | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2017-11-08 18:32:05 +08:00
										 |  |  | 		}; | 
					
						
							| 
									
										
										
										
											2016-12-05 06:47:19 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-08 18:32:05 +08:00
										 |  |  | 		const assignIndexToDependencyBlock = block => { | 
					
						
							| 
									
										
										
										
											2017-03-02 22:09:09 +08:00
										 |  |  | 			let allDependencies = []; | 
					
						
							| 
									
										
										
										
											2016-12-05 06:47:19 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-08 18:32:05 +08:00
										 |  |  | 			const iteratorDependency = d => allDependencies.push(d); | 
					
						
							| 
									
										
										
										
											2016-12-05 06:47:19 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-08 18:32:05 +08:00
										 |  |  | 			const iteratorBlock = b => queue.push(() => assignIndexToDependencyBlock(b)); | 
					
						
							| 
									
										
										
										
											2016-12-05 06:47:19 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-06 01:00:36 +08:00
										 |  |  | 			if(block.variables) { | 
					
						
							| 
									
										
										
										
											2017-01-24 02:52:20 +08:00
										 |  |  | 				iterationBlockVariable(block.variables, iteratorDependency); | 
					
						
							| 
									
										
										
										
											2017-01-06 01:00:36 +08:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2017-01-24 02:52:20 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-06 01:00:36 +08:00
										 |  |  | 			if(block.dependencies) { | 
					
						
							| 
									
										
										
										
											2017-01-24 02:52:20 +08:00
										 |  |  | 				iterationOfArrayCallback(block.dependencies, iteratorDependency); | 
					
						
							| 
									
										
										
										
											2017-01-06 01:00:36 +08:00
										 |  |  | 			} | 
					
						
							|  |  |  | 			if(block.blocks) { | 
					
						
							| 
									
										
										
										
											2017-03-02 22:09:09 +08:00
										 |  |  | 				const blocks = block.blocks; | 
					
						
							|  |  |  | 				let indexBlock = blocks.length; | 
					
						
							| 
									
										
										
										
											2017-01-24 02:52:20 +08:00
										 |  |  | 				while(indexBlock--) { | 
					
						
							|  |  |  | 					iteratorBlock(blocks[indexBlock]); | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2017-01-06 01:00:36 +08:00
										 |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-02 22:09:09 +08:00
										 |  |  | 			let indexAll = allDependencies.length; | 
					
						
							| 
									
										
										
										
											2017-01-24 02:52:20 +08:00
										 |  |  | 			while(indexAll--) { | 
					
						
							|  |  |  | 				iteratorAllDependencies(allDependencies[indexAll]); | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2017-11-08 18:32:05 +08:00
										 |  |  | 		}; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		const queue = [() => { | 
					
						
							|  |  |  | 			assignIndexToModule(module); | 
					
						
							|  |  |  | 		}]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		const iteratorAllDependencies = d => { | 
					
						
							|  |  |  | 			queue.push(() => assignIndexToDependency(d)); | 
					
						
							|  |  |  | 		}; | 
					
						
							| 
									
										
										
										
											2017-01-06 01:00:36 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		while(queue.length) { | 
					
						
							|  |  |  | 			queue.pop()(); | 
					
						
							| 
									
										
										
										
											2016-12-05 06:47:19 +08:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2017-01-06 01:00:36 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	assignDepth(module) { | 
					
						
							| 
									
										
										
										
											2017-11-08 18:32:05 +08:00
										 |  |  | 		const assignDepthToModule = (module, depth) => { | 
					
						
							| 
									
										
										
										
											2017-01-06 01:00:36 +08:00
										 |  |  | 			// enter module
 | 
					
						
							|  |  |  | 			if(typeof module.depth === "number" && module.depth <= depth) return; | 
					
						
							|  |  |  | 			module.depth = depth; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			// enter it as block
 | 
					
						
							|  |  |  | 			assignDepthToDependencyBlock(module, depth + 1); | 
					
						
							| 
									
										
										
										
											2017-11-08 18:32:05 +08:00
										 |  |  | 		}; | 
					
						
							| 
									
										
										
										
											2016-12-05 06:47:19 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-08 18:32:05 +08:00
										 |  |  | 		const assignDepthToDependency = (dependency, depth) => { | 
					
						
							| 
									
										
										
										
											2017-01-06 01:00:36 +08:00
										 |  |  | 			if(dependency.module) { | 
					
						
							|  |  |  | 				queue.push(() => assignDepthToModule(dependency.module, depth)); | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2017-11-08 18:32:05 +08:00
										 |  |  | 		}; | 
					
						
							| 
									
										
										
										
											2016-12-05 06:47:19 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-08 18:32:05 +08:00
										 |  |  | 		const assignDepthToDependencyBlock = (block, depth) => { | 
					
						
							|  |  |  | 			const iteratorDependency = d => assignDepthToDependency(d, depth); | 
					
						
							| 
									
										
										
										
											2016-12-05 06:47:19 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-08 18:32:05 +08:00
										 |  |  | 			const iteratorBlock = b => assignDepthToDependencyBlock(b, depth); | 
					
						
							| 
									
										
										
										
											2016-12-14 19:03:24 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-06 01:00:36 +08:00
										 |  |  | 			if(block.variables) { | 
					
						
							| 
									
										
										
										
											2017-01-24 02:52:20 +08:00
										 |  |  | 				iterationBlockVariable(block.variables, iteratorDependency); | 
					
						
							| 
									
										
										
										
											2017-01-06 01:00:36 +08:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2017-01-24 02:52:20 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-06 01:00:36 +08:00
										 |  |  | 			if(block.dependencies) { | 
					
						
							| 
									
										
										
										
											2017-01-24 02:52:20 +08:00
										 |  |  | 				iterationOfArrayCallback(block.dependencies, iteratorDependency); | 
					
						
							| 
									
										
										
										
											2017-01-06 01:00:36 +08:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2017-01-24 02:52:20 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-06 01:00:36 +08:00
										 |  |  | 			if(block.blocks) { | 
					
						
							| 
									
										
										
										
											2017-01-24 02:52:20 +08:00
										 |  |  | 				iterationOfArrayCallback(block.blocks, iteratorBlock); | 
					
						
							| 
									
										
										
										
											2017-01-06 01:00:36 +08:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2017-11-08 18:32:05 +08:00
										 |  |  | 		}; | 
					
						
							| 
									
										
										
										
											2016-12-14 19:03:24 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-06 01:00:36 +08:00
										 |  |  | 		const queue = [() => { | 
					
						
							|  |  |  | 			assignDepthToModule(module, 0); | 
					
						
							|  |  |  | 		}]; | 
					
						
							| 
									
										
										
										
											2017-11-08 18:32:05 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-06 01:00:36 +08:00
										 |  |  | 		while(queue.length) { | 
					
						
							|  |  |  | 			queue.pop()(); | 
					
						
							| 
									
										
										
										
											2016-12-14 19:03:24 +08:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-10-11 15:44:45 +08:00
										 |  |  | 	// This method creates the Chunk graph from the Module graph
 | 
					
						
							| 
									
										
										
										
											2017-10-11 15:38:09 +08:00
										 |  |  | 	processDependenciesBlocksForChunks(inputChunks) { | 
					
						
							| 
									
										
										
										
											2017-10-11 15:44:45 +08:00
										 |  |  | 		// Process is splitting into two parts:
 | 
					
						
							|  |  |  | 		// Part one traverse the module graph and builds a very basic chunks graph
 | 
					
						
							|  |  |  | 		//   in chunkDependencies.
 | 
					
						
							|  |  |  | 		// Part two traverse every possible way through the basic chunk graph and
 | 
					
						
							|  |  |  | 		//   tracks the available modules. While traversing it connects chunks with
 | 
					
						
							|  |  |  | 		//   eachother and Blocks with Chunks. It stops traversing when all modules
 | 
					
						
							|  |  |  | 		//   for a chunk are already available. So it doesn't connect unneeded chunks.
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-09 16:30:36 +08:00
										 |  |  | 		const chunkDependencies = new Map(); // Map<Chunk, Array<{Module, Chunk}>>
 | 
					
						
							| 
									
										
										
										
											2017-10-11 15:44:45 +08:00
										 |  |  | 		const allCreatedChunks = new Set(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		// PART ONE
 | 
					
						
							| 
									
										
										
										
											2017-06-09 16:30:36 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-10-11 15:44:45 +08:00
										 |  |  | 		const blockChunks = new Map(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		// Start with the provided modules/chunks
 | 
					
						
							| 
									
										
										
										
											2017-10-11 15:38:09 +08:00
										 |  |  | 		const queue = inputChunks.map(chunk => ({ | 
					
						
							|  |  |  | 			block: chunk.entryModule, | 
					
						
							|  |  |  | 			chunk: chunk | 
					
						
							|  |  |  | 		})); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-10-11 15:44:45 +08:00
										 |  |  | 		let block, chunk; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		// For each async Block in graph
 | 
					
						
							| 
									
										
										
										
											2017-01-24 02:52:20 +08:00
										 |  |  | 		const iteratorBlock = b => { | 
					
						
							| 
									
										
										
										
											2017-10-11 15:44:45 +08:00
										 |  |  | 			// 1. We create a chunk for this Block
 | 
					
						
							|  |  |  | 			// but only once (blockChunks map)
 | 
					
						
							|  |  |  | 			let c = blockChunks.get(b); | 
					
						
							|  |  |  | 			if(c === undefined) { | 
					
						
							| 
									
										
										
										
											2017-10-17 15:06:05 +08:00
										 |  |  | 				c = this.namedChunks[b.chunkName]; | 
					
						
							|  |  |  | 				if(c && c.isInitial()) { | 
					
						
							|  |  |  | 					// TODO webpack 4: convert this to an error
 | 
					
						
							|  |  |  | 					this.warnings.push(new AsyncDependencyToInitialChunkWarning(b.chunkName, b.module, b.loc)); | 
					
						
							|  |  |  | 					c = chunk; | 
					
						
							|  |  |  | 				} else { | 
					
						
							|  |  |  | 					c = this.addChunk(b.chunkName, b.module, b.loc); | 
					
						
							|  |  |  | 					blockChunks.set(b, c); | 
					
						
							|  |  |  | 					allCreatedChunks.add(c); | 
					
						
							|  |  |  | 					// We initialize the chunks property
 | 
					
						
							|  |  |  | 					// this is later filled with the chunk when needed
 | 
					
						
							|  |  |  | 					b.chunks = []; | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2017-01-06 01:00:36 +08:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2017-10-11 15:44:45 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			// 2. We store the Block+Chunk mapping as dependency for the chunk
 | 
					
						
							| 
									
										
										
										
											2017-06-09 16:30:36 +08:00
										 |  |  | 			let deps = chunkDependencies.get(chunk); | 
					
						
							|  |  |  | 			if(!deps) chunkDependencies.set(chunk, deps = []); | 
					
						
							|  |  |  | 			deps.push({ | 
					
						
							| 
									
										
										
										
											2017-10-11 15:44:45 +08:00
										 |  |  | 				block: b, | 
					
						
							|  |  |  | 				chunk: c | 
					
						
							| 
									
										
										
										
											2017-06-09 16:30:36 +08:00
										 |  |  | 			}); | 
					
						
							| 
									
										
										
										
											2017-10-11 15:44:45 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			// 3. We enqueue the DependenciesBlock for traversal
 | 
					
						
							| 
									
										
										
										
											2017-06-09 16:30:36 +08:00
										 |  |  | 			queue.push({ | 
					
						
							|  |  |  | 				block: b, | 
					
						
							|  |  |  | 				chunk: c | 
					
						
							|  |  |  | 			}); | 
					
						
							| 
									
										
										
										
											2017-01-24 02:52:20 +08:00
										 |  |  | 		}; | 
					
						
							| 
									
										
										
										
											2016-12-14 19:03:24 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-10-11 15:44:45 +08:00
										 |  |  | 		// For each Dependency in the graph
 | 
					
						
							| 
									
										
										
										
											2017-01-24 02:52:20 +08:00
										 |  |  | 		const iteratorDependency = d => { | 
					
						
							| 
									
										
										
										
											2017-10-12 01:26:00 +08:00
										 |  |  | 			// We skip Dependencies without Reference
 | 
					
						
							| 
									
										
										
										
											2017-08-08 15:28:34 +08:00
										 |  |  | 			const ref = d.getReference(); | 
					
						
							|  |  |  | 			if(!ref) { | 
					
						
							|  |  |  | 				return; | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2017-10-11 15:44:45 +08:00
										 |  |  | 			// We skip Dependencies without Module pointer
 | 
					
						
							| 
									
										
										
										
											2017-08-08 15:28:34 +08:00
										 |  |  | 			const refModule = ref.module; | 
					
						
							|  |  |  | 			if(!refModule) { | 
					
						
							| 
									
										
										
										
											2017-01-06 01:00:36 +08:00
										 |  |  | 				return; | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2017-10-11 15:44:45 +08:00
										 |  |  | 			// We skip weak Dependencies
 | 
					
						
							| 
									
										
										
										
											2017-11-22 15:05:07 +08:00
										 |  |  | 			if(ref.weak) { | 
					
						
							| 
									
										
										
										
											2017-01-06 01:00:36 +08:00
										 |  |  | 				return; | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2017-10-11 15:44:45 +08:00
										 |  |  | 			// We connect Module and Chunk when not already done
 | 
					
						
							| 
									
										
										
										
											2017-08-08 15:28:34 +08:00
										 |  |  | 			if(chunk.addModule(refModule)) { | 
					
						
							|  |  |  | 				refModule.addChunk(chunk); | 
					
						
							| 
									
										
										
										
											2017-10-11 15:44:45 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 				// And enqueue the Module for traversal
 | 
					
						
							| 
									
										
										
										
											2017-06-09 16:30:36 +08:00
										 |  |  | 				queue.push({ | 
					
						
							| 
									
										
										
										
											2017-08-08 15:28:34 +08:00
										 |  |  | 					block: refModule, | 
					
						
							|  |  |  | 					module: refModule, | 
					
						
							| 
									
										
										
										
											2017-06-09 16:30:36 +08:00
										 |  |  | 					chunk | 
					
						
							|  |  |  | 				}); | 
					
						
							| 
									
										
										
										
											2017-01-06 01:00:36 +08:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2017-01-24 02:52:20 +08:00
										 |  |  | 		}; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-10-11 15:44:45 +08:00
										 |  |  | 		// Iterative traversal of the Module graph
 | 
					
						
							|  |  |  | 		// Recursive would be simpler to write but could result in Stack Overflows
 | 
					
						
							| 
									
										
										
										
											2017-01-24 02:52:20 +08:00
										 |  |  | 		while(queue.length) { | 
					
						
							| 
									
										
										
										
											2017-03-02 22:09:09 +08:00
										 |  |  | 			const queueItem = queue.pop(); | 
					
						
							| 
									
										
										
										
											2017-06-09 16:30:36 +08:00
										 |  |  | 			block = queueItem.block; | 
					
						
							|  |  |  | 			chunk = queueItem.chunk; | 
					
						
							| 
									
										
										
										
											2017-01-24 02:52:20 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-10-11 15:44:45 +08:00
										 |  |  | 			// Traverse all variables, Dependencies and Blocks
 | 
					
						
							| 
									
										
										
										
											2017-01-24 02:52:20 +08:00
										 |  |  | 			if(block.variables) { | 
					
						
							|  |  |  | 				iterationBlockVariable(block.variables, iteratorDependency); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			if(block.dependencies) { | 
					
						
							|  |  |  | 				iterationOfArrayCallback(block.dependencies, iteratorDependency); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			if(block.blocks) { | 
					
						
							|  |  |  | 				iterationOfArrayCallback(block.blocks, iteratorBlock); | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2016-12-14 19:03:24 +08:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2017-06-09 16:30:36 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-10-11 15:44:45 +08:00
										 |  |  | 		// PART TWO
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		let availableModules; | 
					
						
							|  |  |  | 		let newAvailableModules; | 
					
						
							| 
									
										
										
										
											2017-10-13 01:12:48 +08:00
										 |  |  | 		const queue2 = new Queue(inputChunks.map(chunk => ({ | 
					
						
							| 
									
										
										
										
											2017-06-09 16:30:36 +08:00
										 |  |  | 			chunk, | 
					
						
							| 
									
										
										
										
											2017-10-11 15:44:45 +08:00
										 |  |  | 			availableModules: new Set() | 
					
						
							| 
									
										
										
										
											2017-10-13 01:12:48 +08:00
										 |  |  | 		}))); | 
					
						
							| 
									
										
										
										
											2017-06-09 16:30:36 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-10-11 15:44:45 +08:00
										 |  |  | 		// Helper function to check if all modules of a chunk are available
 | 
					
						
							|  |  |  | 		const areModulesAvailable = (chunk, availableModules) => { | 
					
						
							|  |  |  | 			for(const module of chunk.modulesIterable) { | 
					
						
							|  |  |  | 				if(!availableModules.has(module)) | 
					
						
							| 
									
										
										
										
											2017-06-15 04:46:26 +08:00
										 |  |  | 					return false; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			return true; | 
					
						
							|  |  |  | 		}; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-10-11 15:44:45 +08:00
										 |  |  | 		// For each edge in the basic chunk graph
 | 
					
						
							|  |  |  | 		const filterFn = dep => { | 
					
						
							|  |  |  | 			// Filter egdes that are not needed because all modules are already available
 | 
					
						
							|  |  |  | 			// This also filters circular dependencies in the chunks graph
 | 
					
						
							|  |  |  | 			const depChunk = dep.chunk; | 
					
						
							|  |  |  | 			if(areModulesAvailable(depChunk, newAvailableModules)) | 
					
						
							|  |  |  | 				return false; // break all modules are already available
 | 
					
						
							|  |  |  | 			return true; | 
					
						
							|  |  |  | 		}; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		const minAvailableModulesMap = new Map(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		// Iterative traversing of the basic chunk graph
 | 
					
						
							| 
									
										
										
										
											2017-06-09 16:30:36 +08:00
										 |  |  | 		while(queue2.length) { | 
					
						
							| 
									
										
										
										
											2017-10-13 01:12:48 +08:00
										 |  |  | 			const queueItem = queue2.dequeue(); | 
					
						
							| 
									
										
										
										
											2017-06-09 16:30:36 +08:00
										 |  |  | 			chunk = queueItem.chunk; | 
					
						
							| 
									
										
										
										
											2017-10-11 15:44:45 +08:00
										 |  |  | 			availableModules = queueItem.availableModules; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			// 1. Get minimal available modules
 | 
					
						
							|  |  |  | 			// It doesn't make sense to traverse a chunk again with more available modules.
 | 
					
						
							|  |  |  | 			// This step calculates the minimal available modules and skips traversal when
 | 
					
						
							|  |  |  | 			// the list didn't shrink.
 | 
					
						
							|  |  |  | 			let minAvailableModules = minAvailableModulesMap.get(chunk); | 
					
						
							|  |  |  | 			if(minAvailableModules === undefined) { | 
					
						
							|  |  |  | 				minAvailableModulesMap.set(chunk, new Set(availableModules)); | 
					
						
							|  |  |  | 			} else { | 
					
						
							|  |  |  | 				let deletedModules = false; | 
					
						
							|  |  |  | 				for(const m of minAvailableModules) { | 
					
						
							|  |  |  | 					if(!availableModules.has(m)) { | 
					
						
							|  |  |  | 						minAvailableModules.delete(m); | 
					
						
							|  |  |  | 						deletedModules = true; | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				if(!deletedModules) | 
					
						
							|  |  |  | 					continue; | 
					
						
							| 
									
										
										
										
											2017-10-13 01:12:48 +08:00
										 |  |  | 				availableModules = minAvailableModules; | 
					
						
							| 
									
										
										
										
											2017-10-11 15:44:45 +08:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2017-06-09 16:30:36 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-10-11 15:44:45 +08:00
										 |  |  | 			// 2. Get the edges at this point of the graph
 | 
					
						
							| 
									
										
										
										
											2017-06-09 16:30:36 +08:00
										 |  |  | 			const deps = chunkDependencies.get(chunk); | 
					
						
							|  |  |  | 			if(!deps) continue; | 
					
						
							| 
									
										
										
										
											2017-10-11 15:44:45 +08:00
										 |  |  | 			if(deps.length === 0) continue; | 
					
						
							| 
									
										
										
										
											2017-06-09 16:30:36 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-10-11 15:44:45 +08:00
										 |  |  | 			// 3. Create a new Set of available modules at this points
 | 
					
						
							|  |  |  | 			newAvailableModules = new Set(availableModules); | 
					
						
							|  |  |  | 			for(const m of chunk.modulesIterable) | 
					
						
							|  |  |  | 				newAvailableModules.add(m); | 
					
						
							| 
									
										
										
										
											2017-06-09 16:30:36 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-10-11 15:44:45 +08:00
										 |  |  | 			// 4. Filter edges with available modules
 | 
					
						
							|  |  |  | 			const filteredDeps = deps.filter(filterFn); | 
					
						
							| 
									
										
										
										
											2017-06-09 16:30:36 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-10-11 15:44:45 +08:00
										 |  |  | 			// 5. Foreach remaining edge
 | 
					
						
							|  |  |  | 			const nextChunks = new Set(); | 
					
						
							|  |  |  | 			for(let i = 0; i < filteredDeps.length; i++) { | 
					
						
							|  |  |  | 				const dep = filteredDeps[i]; | 
					
						
							| 
									
										
										
										
											2017-06-09 16:30:36 +08:00
										 |  |  | 				const depChunk = dep.chunk; | 
					
						
							| 
									
										
										
										
											2017-10-11 15:44:45 +08:00
										 |  |  | 				const depBlock = dep.block; | 
					
						
							| 
									
										
										
										
											2017-06-09 16:30:36 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-10-11 15:44:45 +08:00
										 |  |  | 				// 6. Connnect block with chunk
 | 
					
						
							|  |  |  | 				if(depChunk.addBlock(depBlock)) { | 
					
						
							|  |  |  | 					depBlock.chunks.push(depChunk); | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				// 7. Connect chunk with parent
 | 
					
						
							|  |  |  | 				if(chunk.addChunk(depChunk)) { | 
					
						
							|  |  |  | 					depChunk.addParent(chunk); | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				nextChunks.add(depChunk); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			// 8. Enqueue further traversal
 | 
					
						
							|  |  |  | 			for(const nextChunk of nextChunks) { | 
					
						
							| 
									
										
										
										
											2017-10-13 01:12:48 +08:00
										 |  |  | 				queue2.enqueue({ | 
					
						
							| 
									
										
										
										
											2017-10-11 15:44:45 +08:00
										 |  |  | 					chunk: nextChunk, | 
					
						
							|  |  |  | 					availableModules: newAvailableModules | 
					
						
							| 
									
										
										
										
											2017-06-09 16:30:36 +08:00
										 |  |  | 				}); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2017-10-11 15:44:45 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		// Remove all unconnected chunks
 | 
					
						
							|  |  |  | 		for(const chunk of allCreatedChunks) { | 
					
						
							| 
									
										
										
										
											2017-10-12 01:26:00 +08:00
										 |  |  | 			if(chunk.getNumberOfParents() === 0) | 
					
						
							| 
									
										
										
										
											2017-10-11 15:44:45 +08:00
										 |  |  | 				chunk.remove("unconnected"); | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2016-12-14 19:03:24 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 20:02:35 +08:00
										 |  |  | 	removeReasonsOfDependencyBlock(module, block) { | 
					
						
							| 
									
										
										
										
											2017-01-24 02:52:20 +08:00
										 |  |  | 		const iteratorDependency = d => { | 
					
						
							| 
									
										
										
										
											2017-01-06 01:00:36 +08:00
										 |  |  | 			if(!d.module) { | 
					
						
							|  |  |  | 				return; | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2017-11-06 20:02:35 +08:00
										 |  |  | 			if(d.module.removeReason(module, d)) { | 
					
						
							|  |  |  | 				d.module.forEachChunk(chunk => this.patchChunksAfterReasonRemoval(d.module, chunk)); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		}; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if(block.blocks) { | 
					
						
							|  |  |  | 			iterationOfArrayCallback(block.blocks, block => this.removeReasonsOfDependencyBlock(module, block)); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if(block.dependencies) { | 
					
						
							|  |  |  | 			iterationOfArrayCallback(block.dependencies, iteratorDependency); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if(block.variables) { | 
					
						
							|  |  |  | 			iterationBlockVariable(block.variables, iteratorDependency); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	patchChunksAfterReasonRemoval(module, chunk) { | 
					
						
							|  |  |  | 		if(!module.hasReasons()) { | 
					
						
							|  |  |  | 			this.removeReasonsOfDependencyBlock(module, module); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		if(!module.hasReasonForChunk(chunk)) { | 
					
						
							|  |  |  | 			if(module.removeChunk(chunk)) { | 
					
						
							|  |  |  | 				this.removeChunkFromDependencies(module, chunk); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	removeChunkFromDependencies(block, chunk) { | 
					
						
							|  |  |  | 		const iteratorDependency = d => { | 
					
						
							|  |  |  | 			if(!d.module) { | 
					
						
							|  |  |  | 				return; | 
					
						
							| 
									
										
										
										
											2017-01-06 01:00:36 +08:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2017-11-06 20:02:35 +08:00
										 |  |  | 			this.patchChunksAfterReasonRemoval(d.module, chunk); | 
					
						
							| 
									
										
										
										
											2017-01-24 02:52:20 +08:00
										 |  |  | 		}; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-02 22:09:09 +08:00
										 |  |  | 		const blocks = block.blocks; | 
					
						
							|  |  |  | 		for(let indexBlock = 0; indexBlock < blocks.length; indexBlock++) { | 
					
						
							|  |  |  | 			const chunks = blocks[indexBlock].chunks; | 
					
						
							|  |  |  | 			for(let indexChunk = 0; indexChunk < chunks.length; indexChunk++) { | 
					
						
							|  |  |  | 				const blockChunk = chunks[indexChunk]; | 
					
						
							| 
									
										
										
										
											2017-01-24 02:52:20 +08:00
										 |  |  | 				chunk.removeChunk(blockChunk); | 
					
						
							|  |  |  | 				blockChunk.removeParent(chunk); | 
					
						
							|  |  |  | 				this.removeChunkFromDependencies(chunks, blockChunk); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if(block.dependencies) { | 
					
						
							|  |  |  | 			iterationOfArrayCallback(block.dependencies, iteratorDependency); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if(block.variables) { | 
					
						
							|  |  |  | 			iterationBlockVariable(block.variables, iteratorDependency); | 
					
						
							| 
									
										
										
										
											2016-12-05 06:47:19 +08:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2014-11-02 19:17:05 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-07-08 20:15:21 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-06 01:00:36 +08:00
										 |  |  | 	applyModuleIds() { | 
					
						
							| 
									
										
										
										
											2017-03-02 22:09:09 +08:00
										 |  |  | 		let unusedIds = []; | 
					
						
							|  |  |  | 		let nextFreeModuleId = 0; | 
					
						
							|  |  |  | 		let usedIds = []; | 
					
						
							| 
									
										
										
										
											2017-01-26 03:47:11 +08:00
										 |  |  | 		// TODO consider Map when performance has improved https://gist.github.com/sokra/234c077e1299b7369461f1708519c392
 | 
					
						
							| 
									
										
										
										
											2017-03-02 22:09:09 +08:00
										 |  |  | 		const usedIdMap = Object.create(null); | 
					
						
							| 
									
										
										
										
											2017-01-06 01:00:36 +08:00
										 |  |  | 		if(this.usedModuleIds) { | 
					
						
							|  |  |  | 			Object.keys(this.usedModuleIds).forEach(key => { | 
					
						
							|  |  |  | 				const id = this.usedModuleIds[key]; | 
					
						
							| 
									
										
										
										
											2017-01-26 03:39:24 +08:00
										 |  |  | 				if(!usedIdMap[id]) { | 
					
						
							| 
									
										
										
										
											2017-01-06 01:00:36 +08:00
										 |  |  | 					usedIds.push(id); | 
					
						
							| 
									
										
										
										
											2017-01-26 03:39:24 +08:00
										 |  |  | 					usedIdMap[id] = true; | 
					
						
							| 
									
										
										
										
											2017-01-06 01:00:36 +08:00
										 |  |  | 				} | 
					
						
							|  |  |  | 			}); | 
					
						
							| 
									
										
										
										
											2014-07-19 20:32:48 +08:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2017-01-24 02:52:20 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-02 22:09:09 +08:00
										 |  |  | 		const modules1 = this.modules; | 
					
						
							|  |  |  | 		for(let indexModule1 = 0; indexModule1 < modules1.length; indexModule1++) { | 
					
						
							|  |  |  | 			const module1 = modules1[indexModule1]; | 
					
						
							| 
									
										
										
										
											2017-01-26 03:39:24 +08:00
										 |  |  | 			if(module1.id && !usedIdMap[module1.id]) { | 
					
						
							| 
									
										
										
										
											2017-01-24 02:52:20 +08:00
										 |  |  | 				usedIds.push(module1.id); | 
					
						
							| 
									
										
										
										
											2017-01-26 03:39:24 +08:00
										 |  |  | 				usedIdMap[module1.id] = true; | 
					
						
							| 
									
										
										
										
											2014-07-19 20:32:48 +08:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2017-01-24 02:52:20 +08:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-06 01:00:36 +08:00
										 |  |  | 		if(usedIds.length > 0) { | 
					
						
							| 
									
										
										
										
											2017-03-02 22:09:09 +08:00
										 |  |  | 			let usedIdMax = -1; | 
					
						
							|  |  |  | 			for(let index = 0; index < usedIds.length; index++) { | 
					
						
							|  |  |  | 				const usedIdKey = usedIds[index]; | 
					
						
							| 
									
										
										
										
											2017-01-26 03:39:24 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 				if(typeof usedIdKey !== "number") { | 
					
						
							|  |  |  | 					continue; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				usedIdMax = Math.max(usedIdMax, usedIdKey); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-02 22:09:09 +08:00
										 |  |  | 			let lengthFreeModules = nextFreeModuleId = usedIdMax + 1; | 
					
						
							| 
									
										
										
										
											2017-01-26 03:39:24 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			while(lengthFreeModules--) { | 
					
						
							|  |  |  | 				if(!usedIdMap[lengthFreeModules]) { | 
					
						
							|  |  |  | 					unusedIds.push(lengthFreeModules); | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2016-09-14 18:04:42 +08:00
										 |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2017-01-24 02:52:20 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-02 22:09:09 +08:00
										 |  |  | 		const modules2 = this.modules; | 
					
						
							|  |  |  | 		for(let indexModule2 = 0; indexModule2 < modules2.length; indexModule2++) { | 
					
						
							|  |  |  | 			const module2 = modules2[indexModule2]; | 
					
						
							| 
									
										
										
										
											2017-01-24 02:52:20 +08:00
										 |  |  | 			if(module2.id === null) { | 
					
						
							| 
									
										
										
										
											2017-01-06 01:00:36 +08:00
										 |  |  | 				if(unusedIds.length > 0) | 
					
						
							| 
									
										
										
										
											2017-01-24 02:52:20 +08:00
										 |  |  | 					module2.id = unusedIds.pop(); | 
					
						
							| 
									
										
										
										
											2017-01-06 01:00:36 +08:00
										 |  |  | 				else | 
					
						
							| 
									
										
										
										
											2017-01-24 02:52:20 +08:00
										 |  |  | 					module2.id = nextFreeModuleId++; | 
					
						
							| 
									
										
										
										
											2017-01-06 01:00:36 +08:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2017-01-24 02:52:20 +08:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2016-07-18 06:41:26 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-01-06 01:00:36 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	applyChunkIds() { | 
					
						
							|  |  |  | 		const unusedIds = []; | 
					
						
							|  |  |  | 		let nextFreeChunkId = 0; | 
					
						
							| 
									
										
										
										
											2017-01-24 02:52:20 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-08 18:32:05 +08:00
										 |  |  | 		if(this.usedChunkIds) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			const keyChunks = Object.keys(this.usedChunkIds); | 
					
						
							| 
									
										
										
										
											2017-01-24 02:52:20 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-02 22:09:09 +08:00
										 |  |  | 			for(let index = 0; index < keyChunks.length; index++) { | 
					
						
							|  |  |  | 				const usedIdKey = keyChunks[index]; | 
					
						
							| 
									
										
										
										
											2017-11-08 18:32:05 +08:00
										 |  |  | 				const usedIdValue = this.usedChunkIds[usedIdKey]; | 
					
						
							| 
									
										
										
										
											2017-01-24 02:52:20 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 				if(typeof usedIdValue !== "number") { | 
					
						
							|  |  |  | 					continue; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-08 18:32:05 +08:00
										 |  |  | 				nextFreeChunkId = Math.max(nextFreeChunkId - 1, usedIdValue) + 1; | 
					
						
							| 
									
										
										
										
											2017-01-24 02:52:20 +08:00
										 |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-02 22:09:09 +08:00
										 |  |  | 			let index = nextFreeChunkId; | 
					
						
							| 
									
										
										
										
											2017-01-26 03:39:24 +08:00
										 |  |  | 			while(index--) { | 
					
						
							|  |  |  | 				if(this.usedChunkIds[index] !== index) { | 
					
						
							|  |  |  | 					unusedIds.push(index); | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2017-01-06 01:00:36 +08:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2013-05-08 19:28:54 +08:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2017-01-24 02:52:20 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-02 22:09:09 +08:00
										 |  |  | 		const chunks = this.chunks; | 
					
						
							|  |  |  | 		for(let indexChunk = 0; indexChunk < chunks.length; indexChunk++) { | 
					
						
							|  |  |  | 			const chunk = chunks[indexChunk]; | 
					
						
							| 
									
										
										
										
											2017-01-06 01:00:36 +08:00
										 |  |  | 			if(chunk.id === null) { | 
					
						
							|  |  |  | 				if(unusedIds.length > 0) | 
					
						
							|  |  |  | 					chunk.id = unusedIds.pop(); | 
					
						
							|  |  |  | 				else | 
					
						
							|  |  |  | 					chunk.id = nextFreeChunkId++; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			if(!chunk.ids) { | 
					
						
							|  |  |  | 				chunk.ids = [chunk.id]; | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2017-01-24 02:52:20 +08:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2016-07-18 06:41:26 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2013-01-31 01:49:25 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-06 01:00:36 +08:00
										 |  |  | 	sortItemsWithModuleIds() { | 
					
						
							|  |  |  | 		this.modules.sort(byId); | 
					
						
							| 
									
										
										
										
											2017-01-24 02:52:20 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-02 22:09:09 +08:00
										 |  |  | 		const modules = this.modules; | 
					
						
							|  |  |  | 		for(let indexModule = 0; indexModule < modules.length; indexModule++) { | 
					
						
							| 
									
										
										
										
											2017-04-19 13:57:21 +08:00
										 |  |  | 			modules[indexModule].sortItems(false); | 
					
						
							| 
									
										
										
										
											2017-01-24 02:52:20 +08:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-02 22:09:09 +08:00
										 |  |  | 		const chunks = this.chunks; | 
					
						
							|  |  |  | 		for(let indexChunk = 0; indexChunk < chunks.length; indexChunk++) { | 
					
						
							| 
									
										
										
										
											2017-09-22 23:23:49 +08:00
										 |  |  | 			chunks[indexChunk].sortItems(false); | 
					
						
							| 
									
										
										
										
											2017-01-24 02:52:20 +08:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2017-01-06 01:00:36 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	sortItemsWithChunkIds() { | 
					
						
							|  |  |  | 		this.chunks.sort(byId); | 
					
						
							| 
									
										
										
										
											2017-01-24 02:52:20 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-02 22:09:09 +08:00
										 |  |  | 		const modules = this.modules; | 
					
						
							|  |  |  | 		for(let indexModule = 0; indexModule < modules.length; indexModule++) { | 
					
						
							| 
									
										
										
										
											2017-04-19 13:57:21 +08:00
										 |  |  | 			modules[indexModule].sortItems(true); | 
					
						
							| 
									
										
										
										
											2017-01-24 02:52:20 +08:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-02 22:09:09 +08:00
										 |  |  | 		const chunks = this.chunks; | 
					
						
							|  |  |  | 		for(let indexChunk = 0; indexChunk < chunks.length; indexChunk++) { | 
					
						
							| 
									
										
										
										
											2017-09-22 23:23:49 +08:00
										 |  |  | 			chunks[indexChunk].sortItems(true); | 
					
						
							| 
									
										
										
										
											2017-01-24 02:52:20 +08:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2017-08-11 20:35:08 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		const byMessage = (a, b) => { | 
					
						
							|  |  |  | 			const ma = `${a.message}`; | 
					
						
							|  |  |  | 			const mb = `${b.message}`; | 
					
						
							|  |  |  | 			if(ma < mb) return -1; | 
					
						
							|  |  |  | 			if(mb < ma) return 1; | 
					
						
							|  |  |  | 			return 0; | 
					
						
							| 
									
										
										
										
											2017-08-11 22:58:18 +08:00
										 |  |  | 		}; | 
					
						
							| 
									
										
										
										
											2017-08-11 20:35:08 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		this.errors.sort(byMessage); | 
					
						
							|  |  |  | 		this.warnings.sort(byMessage); | 
					
						
							| 
									
										
										
										
											2017-01-06 01:00:36 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	summarizeDependencies() { | 
					
						
							| 
									
										
										
										
											2017-11-06 23:41:26 +08:00
										 |  |  | 		this.fileDependencies = new SortableSet(this.compilationDependencies); | 
					
						
							|  |  |  | 		this.contextDependencies = new SortableSet(); | 
					
						
							|  |  |  | 		this.missingDependencies = new SortableSet(); | 
					
						
							| 
									
										
										
										
											2017-01-24 02:52:20 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-02 22:09:09 +08:00
										 |  |  | 		const children = this.children; | 
					
						
							|  |  |  | 		for(let indexChildren = 0; indexChildren < children.length; indexChildren++) { | 
					
						
							|  |  |  | 			const child = children[indexChildren]; | 
					
						
							| 
									
										
										
										
											2017-01-24 02:52:20 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 23:41:26 +08:00
										 |  |  | 			addAllToSet(this.fileDependencies, child.fileDependencies); | 
					
						
							|  |  |  | 			addAllToSet(this.contextDependencies, child.contextDependencies); | 
					
						
							|  |  |  | 			addAllToSet(this.missingDependencies, child.missingDependencies); | 
					
						
							| 
									
										
										
										
											2017-01-24 02:52:20 +08:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-02 22:09:09 +08:00
										 |  |  | 		const modules = this.modules; | 
					
						
							|  |  |  | 		for(let indexModule = 0; indexModule < modules.length; indexModule++) { | 
					
						
							|  |  |  | 			const module = modules[indexModule]; | 
					
						
							| 
									
										
										
										
											2017-01-24 02:52:20 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-06 01:00:36 +08:00
										 |  |  | 			if(module.fileDependencies) { | 
					
						
							| 
									
										
										
										
											2017-11-06 23:41:26 +08:00
										 |  |  | 				addAllToSet(this.fileDependencies, module.fileDependencies); | 
					
						
							| 
									
										
										
										
											2017-01-06 01:00:36 +08:00
										 |  |  | 			} | 
					
						
							|  |  |  | 			if(module.contextDependencies) { | 
					
						
							| 
									
										
										
										
											2017-11-06 23:41:26 +08:00
										 |  |  | 				addAllToSet(this.contextDependencies, module.contextDependencies); | 
					
						
							| 
									
										
										
										
											2017-01-06 01:00:36 +08:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2017-01-24 02:52:20 +08:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2017-01-06 01:00:36 +08:00
										 |  |  | 		this.errors.forEach(error => { | 
					
						
							| 
									
										
										
										
											2017-11-06 23:41:26 +08:00
										 |  |  | 			if(typeof error.missing === "object" && error.missing && error.missing[Symbol.iterator]) { | 
					
						
							|  |  |  | 				addAllToSet(this.missingDependencies, error.missing); | 
					
						
							| 
									
										
										
										
											2017-01-06 01:00:36 +08:00
										 |  |  | 			} | 
					
						
							|  |  |  | 		}); | 
					
						
							|  |  |  | 		this.fileDependencies.sort(); | 
					
						
							|  |  |  | 		this.contextDependencies.sort(); | 
					
						
							|  |  |  | 		this.missingDependencies.sort(); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	createHash() { | 
					
						
							|  |  |  | 		const outputOptions = this.outputOptions; | 
					
						
							|  |  |  | 		const hashFunction = outputOptions.hashFunction; | 
					
						
							|  |  |  | 		const hashDigest = outputOptions.hashDigest; | 
					
						
							|  |  |  | 		const hashDigestLength = outputOptions.hashDigestLength; | 
					
						
							| 
									
										
										
										
											2017-11-23 17:59:29 +08:00
										 |  |  | 		const hash = createHash(hashFunction); | 
					
						
							| 
									
										
										
										
											2016-06-05 02:03:42 +08:00
										 |  |  | 		if(outputOptions.hashSalt) | 
					
						
							|  |  |  | 			hash.update(outputOptions.hashSalt); | 
					
						
							| 
									
										
										
										
											2017-01-06 01:00:36 +08:00
										 |  |  | 		this.mainTemplate.updateHash(hash); | 
					
						
							|  |  |  | 		this.chunkTemplate.updateHash(hash); | 
					
						
							| 
									
										
										
										
											2017-11-11 18:27:02 +08:00
										 |  |  | 		Object.keys(this.moduleTemplates).sort().forEach(key => this.moduleTemplates[key].updateHash(hash)); | 
					
						
							| 
									
										
										
										
											2017-11-08 18:32:05 +08:00
										 |  |  | 		this.children.forEach(child => hash.update(child.hash)); | 
					
						
							|  |  |  | 		this.warnings.forEach(warning => hash.update(`${warning.message}`)); | 
					
						
							|  |  |  | 		this.errors.forEach(error => hash.update(`${error.message}`)); | 
					
						
							| 
									
										
										
										
											2017-10-30 20:56:57 +08:00
										 |  |  | 		const modules = this.modules; | 
					
						
							|  |  |  | 		for(let i = 0; i < modules.length; i++) { | 
					
						
							|  |  |  | 			const module = modules[i]; | 
					
						
							| 
									
										
										
										
											2017-11-23 17:59:29 +08:00
										 |  |  | 			const moduleHash = createHash(hashFunction); | 
					
						
							| 
									
										
										
										
											2017-10-30 20:56:57 +08:00
										 |  |  | 			module.updateHash(moduleHash); | 
					
						
							|  |  |  | 			module.hash = moduleHash.digest(hashDigest); | 
					
						
							|  |  |  | 			module.renderedHash = module.hash.substr(0, hashDigestLength); | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2017-01-10 20:20:54 +08:00
										 |  |  | 		// clone needed as sort below is inplace mutation
 | 
					
						
							| 
									
										
										
										
											2017-01-06 01:00:36 +08:00
										 |  |  | 		const chunks = this.chunks.slice(); | 
					
						
							| 
									
										
										
										
											2017-01-10 20:20:54 +08:00
										 |  |  | 		/** | 
					
						
							|  |  |  | 		 * sort here will bring all "falsy" values to the beginning | 
					
						
							|  |  |  | 		 * this is needed as the "hasRuntime()" chunks are dependent on the | 
					
						
							|  |  |  | 		 * hashes of the non-runtime chunks. | 
					
						
							|  |  |  | 		 */ | 
					
						
							| 
									
										
										
										
											2017-01-06 01:00:36 +08:00
										 |  |  | 		chunks.sort((a, b) => { | 
					
						
							|  |  |  | 			const aEntry = a.hasRuntime(); | 
					
						
							|  |  |  | 			const bEntry = b.hasRuntime(); | 
					
						
							|  |  |  | 			if(aEntry && !bEntry) return 1; | 
					
						
							|  |  |  | 			if(!aEntry && bEntry) return -1; | 
					
						
							|  |  |  | 			return 0; | 
					
						
							|  |  |  | 		}); | 
					
						
							|  |  |  | 		for(let i = 0; i < chunks.length; i++) { | 
					
						
							| 
									
										
										
										
											2017-02-05 08:18:40 +08:00
										 |  |  | 			const chunk = chunks[i]; | 
					
						
							| 
									
										
										
										
											2017-11-23 17:59:29 +08:00
										 |  |  | 			const chunkHash = createHash(hashFunction); | 
					
						
							| 
									
										
										
										
											2017-01-06 01:00:36 +08:00
										 |  |  | 			if(outputOptions.hashSalt) | 
					
						
							| 
									
										
										
										
											2017-01-10 06:45:59 +08:00
										 |  |  | 				chunkHash.update(outputOptions.hashSalt); | 
					
						
							| 
									
										
										
										
											2017-01-06 01:00:36 +08:00
										 |  |  | 			chunk.updateHash(chunkHash); | 
					
						
							|  |  |  | 			if(chunk.hasRuntime()) { | 
					
						
							|  |  |  | 				this.mainTemplate.updateHashForChunk(chunkHash, chunk); | 
					
						
							|  |  |  | 			} else { | 
					
						
							| 
									
										
										
										
											2017-02-25 04:24:18 +08:00
										 |  |  | 				this.chunkTemplate.updateHashForChunk(chunkHash, chunk); | 
					
						
							| 
									
										
										
										
											2017-01-06 01:00:36 +08:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2017-11-27 22:27:30 +08:00
										 |  |  | 			this.hooks.chunkHash.call(chunk, chunkHash); | 
					
						
							| 
									
										
										
										
											2017-01-06 01:00:36 +08:00
										 |  |  | 			chunk.hash = chunkHash.digest(hashDigest); | 
					
						
							|  |  |  | 			hash.update(chunk.hash); | 
					
						
							|  |  |  | 			chunk.renderedHash = chunk.hash.substr(0, hashDigestLength); | 
					
						
							| 
									
										
										
										
											2015-06-25 05:17:12 +08:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2017-01-06 01:00:36 +08:00
										 |  |  | 		this.fullHash = hash.digest(hashDigest); | 
					
						
							|  |  |  | 		this.hash = this.fullHash.substr(0, hashDigestLength); | 
					
						
							| 
									
										
										
										
											2013-02-13 20:00:01 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-01-06 01:00:36 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	modifyHash(update) { | 
					
						
							|  |  |  | 		const outputOptions = this.outputOptions; | 
					
						
							|  |  |  | 		const hashFunction = outputOptions.hashFunction; | 
					
						
							|  |  |  | 		const hashDigest = outputOptions.hashDigest; | 
					
						
							|  |  |  | 		const hashDigestLength = outputOptions.hashDigestLength; | 
					
						
							| 
									
										
										
										
											2017-11-23 17:59:29 +08:00
										 |  |  | 		const hash = createHash(hashFunction); | 
					
						
							| 
									
										
										
										
											2017-01-06 01:00:36 +08:00
										 |  |  | 		hash.update(this.fullHash); | 
					
						
							|  |  |  | 		hash.update(update); | 
					
						
							|  |  |  | 		this.fullHash = hash.digest(hashDigest); | 
					
						
							|  |  |  | 		this.hash = this.fullHash.substr(0, hashDigestLength); | 
					
						
							| 
									
										
										
										
											2016-10-29 17:11:44 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-06 01:00:36 +08:00
										 |  |  | 	createModuleAssets() { | 
					
						
							|  |  |  | 		for(let i = 0; i < this.modules.length; i++) { | 
					
						
							| 
									
										
										
										
											2017-02-05 08:18:40 +08:00
										 |  |  | 			const module = this.modules[i]; | 
					
						
							| 
									
										
										
										
											2017-01-06 01:00:36 +08:00
										 |  |  | 			if(module.assets) { | 
					
						
							| 
									
										
										
										
											2017-02-05 10:28:15 +08:00
										 |  |  | 				Object.keys(module.assets).forEach((assetName) => { | 
					
						
							|  |  |  | 					const fileName = this.getPath(assetName); | 
					
						
							|  |  |  | 					this.assets[fileName] = module.assets[assetName]; | 
					
						
							| 
									
										
										
										
											2017-11-27 22:27:30 +08:00
										 |  |  | 					this.hooks.moduleAsset.call(module, fileName); | 
					
						
							| 
									
										
										
										
											2017-02-05 10:28:15 +08:00
										 |  |  | 				}); | 
					
						
							| 
									
										
										
										
											2017-01-06 01:00:36 +08:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2013-01-31 01:49:25 +08:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-01-06 01:00:36 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	createChunkAssets() { | 
					
						
							|  |  |  | 		const outputOptions = this.outputOptions; | 
					
						
							|  |  |  | 		for(let i = 0; i < this.chunks.length; i++) { | 
					
						
							|  |  |  | 			const chunk = this.chunks[i]; | 
					
						
							|  |  |  | 			chunk.files = []; | 
					
						
							|  |  |  | 			let source; | 
					
						
							|  |  |  | 			let file; | 
					
						
							| 
									
										
										
										
											2017-10-30 20:56:57 +08:00
										 |  |  | 			let filenameTemplate; | 
					
						
							| 
									
										
										
										
											2017-01-06 01:00:36 +08:00
										 |  |  | 			try { | 
					
						
							| 
									
										
										
										
											2017-10-30 20:56:57 +08:00
										 |  |  | 				const template = chunk.hasRuntime() ? this.mainTemplate : this.chunkTemplate; | 
					
						
							|  |  |  | 				const manifest = template.getRenderManifest({ | 
					
						
							|  |  |  | 					chunk, | 
					
						
							|  |  |  | 					hash: this.hash, | 
					
						
							|  |  |  | 					fullHash: this.fullHash, | 
					
						
							|  |  |  | 					outputOptions, | 
					
						
							|  |  |  | 					moduleTemplates: this.moduleTemplates, | 
					
						
							|  |  |  | 					dependencyTemplates: this.dependencyTemplates | 
					
						
							|  |  |  | 				}); // [{ render(), filenameTemplate, pathOptions, identifier, hash }]
 | 
					
						
							|  |  |  | 				for(const fileManifest of manifest) { | 
					
						
							|  |  |  | 					const cacheName = fileManifest.identifier; | 
					
						
							|  |  |  | 					const usedHash = fileManifest.hash; | 
					
						
							|  |  |  | 					filenameTemplate = fileManifest.filenameTemplate; | 
					
						
							|  |  |  | 					if(this.cache && this.cache[cacheName] && this.cache[cacheName].hash === usedHash) { | 
					
						
							|  |  |  | 						source = this.cache[cacheName].source; | 
					
						
							| 
									
										
										
										
											2017-01-06 01:00:36 +08:00
										 |  |  | 					} else { | 
					
						
							| 
									
										
										
										
											2017-10-30 20:56:57 +08:00
										 |  |  | 						source = fileManifest.render(); | 
					
						
							|  |  |  | 						if(this.cache) { | 
					
						
							|  |  |  | 							this.cache[cacheName] = { | 
					
						
							|  |  |  | 								hash: usedHash, | 
					
						
							|  |  |  | 								source: source = (source instanceof CachedSource ? source : new CachedSource(source)) | 
					
						
							|  |  |  | 							}; | 
					
						
							|  |  |  | 						} | 
					
						
							| 
									
										
										
										
											2017-01-06 01:00:36 +08:00
										 |  |  | 					} | 
					
						
							| 
									
										
										
										
											2017-10-30 20:56:57 +08:00
										 |  |  | 					file = this.getPath(filenameTemplate, fileManifest.pathOptions); | 
					
						
							|  |  |  | 					if(this.assets[file] && this.assets[file] !== source) | 
					
						
							|  |  |  | 						throw new Error(`Conflict: Multiple assets emit to the same filename ${file}`); | 
					
						
							|  |  |  | 					this.assets[file] = source; | 
					
						
							|  |  |  | 					chunk.files.push(file); | 
					
						
							| 
									
										
										
										
											2017-11-27 22:27:30 +08:00
										 |  |  | 					this.hooks.chunkAsset.call(chunk, file); | 
					
						
							| 
									
										
										
										
											2015-06-27 17:34:17 +08:00
										 |  |  | 				} | 
					
						
							| 
									
										
										
										
											2017-01-06 01:00:36 +08:00
										 |  |  | 			} catch(err) { | 
					
						
							|  |  |  | 				this.errors.push(new ChunkRenderError(chunk, file || filenameTemplate, err)); | 
					
						
							| 
									
										
										
										
											2013-05-08 19:28:54 +08:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2013-12-03 18:19:30 +08:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2013-01-31 01:49:25 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-01-06 01:00:36 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	getPath(filename, data) { | 
					
						
							|  |  |  | 		data = data || {}; | 
					
						
							|  |  |  | 		data.hash = data.hash || this.hash; | 
					
						
							|  |  |  | 		return this.mainTemplate.applyPluginsWaterfall("asset-path", filename, data); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-13 19:43:51 +08:00
										 |  |  | 	createChildCompiler(name, outputOptions, plugins) { | 
					
						
							| 
									
										
										
										
											2017-11-15 16:28:45 +08:00
										 |  |  | 		const idx = (this.childrenCounters[name] || 0); | 
					
						
							| 
									
										
										
										
											2017-04-13 19:43:51 +08:00
										 |  |  | 		this.childrenCounters[name] = idx + 1; | 
					
						
							|  |  |  | 		return this.compiler.createChildCompiler(this, name, idx, outputOptions, plugins); | 
					
						
							| 
									
										
										
										
											2017-01-06 01:00:36 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	checkConstraints() { | 
					
						
							|  |  |  | 		const usedIds = {}; | 
					
						
							| 
									
										
										
										
											2017-01-24 02:52:20 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-02 22:09:09 +08:00
										 |  |  | 		const modules = this.modules; | 
					
						
							|  |  |  | 		for(let indexModule = 0; indexModule < modules.length; indexModule++) { | 
					
						
							|  |  |  | 			const moduleId = modules[indexModule].id; | 
					
						
							| 
									
										
										
										
											2017-01-24 02:52:20 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			if(usedIds[moduleId]) | 
					
						
							|  |  |  | 				throw new Error(`checkConstraints: duplicate module id ${moduleId}`); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-02 22:09:09 +08:00
										 |  |  | 		const chunks = this.chunks; | 
					
						
							|  |  |  | 		for(let indexChunk = 0; indexChunk < chunks.length; indexChunk++) { | 
					
						
							|  |  |  | 			const chunk = chunks[indexChunk]; | 
					
						
							| 
									
										
										
										
											2017-01-24 02:52:20 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			if(chunks.indexOf(chunk) !== indexChunk) | 
					
						
							| 
									
										
										
										
											2017-01-06 01:00:36 +08:00
										 |  |  | 				throw new Error(`checkConstraints: duplicate chunk in compilation ${chunk.debugId}`); | 
					
						
							|  |  |  | 			chunk.checkConstraints(); | 
					
						
							| 
									
										
										
										
											2017-01-24 02:52:20 +08:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2017-01-06 01:00:36 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-11-27 22:27:30 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	applyPlugins(name, ...args) { | 
					
						
							|  |  |  | 		this.hooks[name.replace(/[- ]([a-z])/g, match => match[1].toUpperCase())].call(...args); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-01-06 01:00:36 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-10 18:02:45 +08:00
										 |  |  | Object.defineProperty(Compilation.prototype, "moduleTemplate", { | 
					
						
							|  |  |  | 	configurable: false, | 
					
						
							|  |  |  | 	get: util.deprecate(function() { | 
					
						
							|  |  |  | 		return this.moduleTemplates.javascript; | 
					
						
							|  |  |  | 	}, "Compilation.moduleTemplate: Use Compilation.moduleTemplates.javascript instead"), | 
					
						
							|  |  |  | 	set: util.deprecate(function(value) { | 
					
						
							| 
									
										
										
										
											2017-11-11 18:27:02 +08:00
										 |  |  | 		this.moduleTemplates.javascript = value; | 
					
						
							| 
									
										
										
										
											2017-11-10 18:02:45 +08:00
										 |  |  | 	}, "Compilation.moduleTemplate: Use Compilation.moduleTemplates.javascript instead.") | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-06 01:00:36 +08:00
										 |  |  | module.exports = Compilation; |