| 
									
										
										
										
											2013-01-31 01:49:25 +08:00
										 |  |  | /* | 
					
						
							|  |  |  | 	MIT License http://www.opensource.org/licenses/mit-license.php
 | 
					
						
							|  |  |  | 	Author Tobias Koppers @sokra | 
					
						
							|  |  |  | */ | 
					
						
							| 
									
										
										
										
											2017-02-11 11:16:18 +08:00
										 |  |  | "use strict"; | 
					
						
							| 
									
										
										
										
											2013-01-31 01:49:25 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-11 11:16:18 +08:00
										 |  |  | const path = require("path"); | 
					
						
							|  |  |  | const NativeModule = require("module"); | 
					
						
							| 
									
										
										
										
											2017-02-12 21:08:41 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-11 11:16:18 +08:00
										 |  |  | const SourceMapSource = require("webpack-sources").SourceMapSource; | 
					
						
							|  |  |  | const OriginalSource = require("webpack-sources").OriginalSource; | 
					
						
							|  |  |  | const RawSource = require("webpack-sources").RawSource; | 
					
						
							|  |  |  | const ReplaceSource = require("webpack-sources").ReplaceSource; | 
					
						
							|  |  |  | const CachedSource = require("webpack-sources").CachedSource; | 
					
						
							|  |  |  | const LineToLineMappedSource = require("webpack-sources").LineToLineMappedSource; | 
					
						
							| 
									
										
										
										
											2016-01-04 04:42:56 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-25 05:17:47 +08:00
										 |  |  | const WebpackError = require("./WebpackError"); | 
					
						
							| 
									
										
										
										
											2017-02-12 21:08:41 +08:00
										 |  |  | const Module = require("./Module"); | 
					
						
							|  |  |  | const ModuleParseError = require("./ModuleParseError"); | 
					
						
							| 
									
										
										
										
											2017-02-11 11:16:18 +08:00
										 |  |  | const ModuleBuildError = require("./ModuleBuildError"); | 
					
						
							|  |  |  | const ModuleError = require("./ModuleError"); | 
					
						
							|  |  |  | const ModuleWarning = require("./ModuleWarning"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | const runLoaders = require("loader-runner").runLoaders; | 
					
						
							|  |  |  | const getContext = require("loader-runner").getContext; | 
					
						
							| 
									
										
										
										
											2016-01-04 04:42:56 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-08 18:32:05 +08:00
										 |  |  | const asString = (buf) => { | 
					
						
							| 
									
										
										
										
											2016-01-04 04:42:56 +08:00
										 |  |  | 	if(Buffer.isBuffer(buf)) { | 
					
						
							|  |  |  | 		return buf.toString("utf-8"); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return buf; | 
					
						
							| 
									
										
										
										
											2017-11-08 18:32:05 +08:00
										 |  |  | }; | 
					
						
							| 
									
										
										
										
											2016-01-04 04:42:56 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-10-30 20:56:57 +08:00
										 |  |  | const asBuffer = str => { | 
					
						
							|  |  |  | 	if(!Buffer.isBuffer(str)) { | 
					
						
							|  |  |  | 		return new Buffer(str, "utf-8"); // eslint-disable-line
 | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return str; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-08 18:32:05 +08:00
										 |  |  | const contextify = (context, request) => { | 
					
						
							|  |  |  | 	return request.split("!").map(r => { | 
					
						
							| 
									
										
										
										
											2017-08-30 05:50:22 +08:00
										 |  |  | 		const splitPath = r.split("?"); | 
					
						
							|  |  |  | 		splitPath[0] = path.relative(context, splitPath[0]); | 
					
						
							| 
									
										
										
										
											2015-05-17 00:27:59 +08:00
										 |  |  | 		if(path.sep === "\\") | 
					
						
							| 
									
										
										
										
											2017-08-30 05:50:22 +08:00
										 |  |  | 			splitPath[0] = splitPath[0].replace(/\\/g, "/"); | 
					
						
							|  |  |  | 		if(splitPath[0].indexOf("../") !== 0) | 
					
						
							|  |  |  | 			splitPath[0] = "./" + splitPath[0]; | 
					
						
							|  |  |  | 		return splitPath.join("?"); | 
					
						
							| 
									
										
										
										
											2015-05-17 00:27:59 +08:00
										 |  |  | 	}).join("!"); | 
					
						
							| 
									
										
										
										
											2017-11-08 18:32:05 +08:00
										 |  |  | }; | 
					
						
							| 
									
										
										
										
											2015-05-17 00:27:59 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-25 05:17:47 +08:00
										 |  |  | class NonErrorEmittedError extends WebpackError { | 
					
						
							| 
									
										
										
										
											2017-03-22 20:00:57 +08:00
										 |  |  | 	constructor(error) { | 
					
						
							|  |  |  | 		super(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		this.name = "NonErrorEmittedError"; | 
					
						
							|  |  |  | 		this.message = "(Emitted value instead of an instance of Error) " + error; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		Error.captureStackTrace(this, this.constructor); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-14 18:50:39 +08:00
										 |  |  | const dependencyTemplatesHashMap = new WeakMap(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-11 11:16:18 +08:00
										 |  |  | class NormalModule extends Module { | 
					
						
							| 
									
										
										
										
											2015-05-17 00:27:59 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-17 21:26:23 +08:00
										 |  |  | 	constructor(type, request, userRequest, rawRequest, loaders, resource, parser, resolveOptions) { | 
					
						
							| 
									
										
										
										
											2017-10-30 20:56:57 +08:00
										 |  |  | 		super(type); | 
					
						
							| 
									
										
										
										
											2017-11-06 20:02:35 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		// Info from Factory
 | 
					
						
							| 
									
										
										
										
											2017-02-11 11:16:18 +08:00
										 |  |  | 		this.request = request; | 
					
						
							|  |  |  | 		this.userRequest = userRequest; | 
					
						
							|  |  |  | 		this.rawRequest = rawRequest; | 
					
						
							| 
									
										
										
										
											2017-10-30 20:56:57 +08:00
										 |  |  | 		this.binary = type.startsWith("webassembly"); | 
					
						
							| 
									
										
										
										
											2017-02-11 11:16:18 +08:00
										 |  |  | 		this.parser = parser; | 
					
						
							|  |  |  | 		this.resource = resource; | 
					
						
							|  |  |  | 		this.context = getContext(resource); | 
					
						
							|  |  |  | 		this.loaders = loaders; | 
					
						
							| 
									
										
										
										
											2017-11-17 21:26:23 +08:00
										 |  |  | 		if(resolveOptions !== undefined) | 
					
						
							|  |  |  | 			this.resolveOptions = resolveOptions; | 
					
						
							| 
									
										
										
										
											2017-11-06 20:02:35 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		// Info from Build
 | 
					
						
							| 
									
										
										
										
											2017-02-11 11:16:18 +08:00
										 |  |  | 		this.error = null; | 
					
						
							|  |  |  | 		this._source = null; | 
					
						
							| 
									
										
										
										
											2017-11-06 20:02:35 +08:00
										 |  |  | 		this.buildTimestamp = undefined; | 
					
						
							| 
									
										
										
										
											2017-12-01 18:07:23 +08:00
										 |  |  | 		this._cachedSource = undefined; | 
					
						
							|  |  |  | 		this._cachedSourceHash = undefined; | 
					
						
							| 
									
										
										
										
											2017-11-06 20:02:35 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		// Options for the NormalModule set by plugins
 | 
					
						
							|  |  |  | 		// TODO refactor this -> options object filled from Factory
 | 
					
						
							|  |  |  | 		this.useSourceMap = false; | 
					
						
							|  |  |  | 		this.lineToLine = false; | 
					
						
							| 
									
										
										
										
											2017-12-07 00:26:02 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		// Cache
 | 
					
						
							|  |  |  | 		this._lastSuccessfulBuildMeta = {}; | 
					
						
							| 
									
										
										
										
											2017-02-11 11:16:18 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2016-09-14 18:04:42 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-11 11:16:18 +08:00
										 |  |  | 	identifier() { | 
					
						
							|  |  |  | 		return this.request; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2016-01-04 04:42:56 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-11 11:16:18 +08:00
										 |  |  | 	readableIdentifier(requestShortener) { | 
					
						
							|  |  |  | 		return requestShortener.shorten(this.userRequest); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2016-01-04 04:42:56 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-11 11:16:18 +08:00
										 |  |  | 	libIdent(options) { | 
					
						
							| 
									
										
										
										
											2017-02-14 17:38:47 +08:00
										 |  |  | 		return contextify(options.context, this.userRequest); | 
					
						
							| 
									
										
										
										
											2017-02-11 11:16:18 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2016-01-04 04:42:56 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-11 11:16:18 +08:00
										 |  |  | 	nameForCondition() { | 
					
						
							|  |  |  | 		const idx = this.resource.indexOf("?"); | 
					
						
							|  |  |  | 		if(idx >= 0) return this.resource.substr(0, idx); | 
					
						
							|  |  |  | 		return this.resource; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2013-01-31 01:49:25 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-11 14:07:01 +08:00
										 |  |  | 	createSourceForAsset(name, content, sourceMap) { | 
					
						
							|  |  |  | 		if(!sourceMap) { | 
					
						
							|  |  |  | 			return new RawSource(content); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if(typeof sourceMap === "string") { | 
					
						
							|  |  |  | 			return new OriginalSource(content, sourceMap); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		return new SourceMapSource(content, name, sourceMap); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-11 12:32:48 +08:00
										 |  |  | 	createLoaderContext(resolver, options, compilation, fs) { | 
					
						
							| 
									
										
										
										
											2017-02-11 11:16:18 +08:00
										 |  |  | 		const loaderContext = { | 
					
						
							|  |  |  | 			version: 2, | 
					
						
							|  |  |  | 			emitWarning: (warning) => { | 
					
						
							| 
									
										
										
										
											2017-03-22 20:00:57 +08:00
										 |  |  | 				if(!(warning instanceof Error)) | 
					
						
							|  |  |  | 					warning = new NonErrorEmittedError(warning); | 
					
						
							| 
									
										
										
										
											2017-02-11 12:32:48 +08:00
										 |  |  | 				this.warnings.push(new ModuleWarning(this, warning)); | 
					
						
							| 
									
										
										
										
											2017-02-11 11:16:18 +08:00
										 |  |  | 			}, | 
					
						
							| 
									
										
										
										
											2017-02-11 12:32:48 +08:00
										 |  |  | 			emitError: (error) => { | 
					
						
							| 
									
										
										
										
											2017-03-22 20:00:57 +08:00
										 |  |  | 				if(!(error instanceof Error)) | 
					
						
							|  |  |  | 					error = new NonErrorEmittedError(error); | 
					
						
							| 
									
										
										
										
											2017-02-11 12:32:48 +08:00
										 |  |  | 				this.errors.push(new ModuleError(this, error)); | 
					
						
							| 
									
										
										
										
											2017-02-11 11:16:18 +08:00
										 |  |  | 			}, | 
					
						
							| 
									
										
										
										
											2017-02-11 12:32:48 +08:00
										 |  |  | 			exec: (code, filename) => { | 
					
						
							|  |  |  | 				const module = new NativeModule(filename, this); | 
					
						
							|  |  |  | 				module.paths = NativeModule._nodeModulePaths(this.context); | 
					
						
							|  |  |  | 				module.filename = filename; | 
					
						
							|  |  |  | 				module._compile(code, filename); | 
					
						
							|  |  |  | 				return module.exports; | 
					
						
							| 
									
										
										
										
											2017-02-11 11:16:18 +08:00
										 |  |  | 			}, | 
					
						
							| 
									
										
										
										
											2017-02-12 21:08:41 +08:00
										 |  |  | 			resolve(context, request, callback) { | 
					
						
							| 
									
										
										
										
											2017-02-11 11:16:18 +08:00
										 |  |  | 				resolver.resolve({}, context, request, callback); | 
					
						
							|  |  |  | 			}, | 
					
						
							| 
									
										
										
										
											2017-02-11 12:32:48 +08:00
										 |  |  | 			emitFile: (name, content, sourceMap) => { | 
					
						
							| 
									
										
										
										
											2017-12-06 19:09:17 +08:00
										 |  |  | 				if(!this.buildInfo.assets) this.buildInfo.assets = Object.create(null); | 
					
						
							|  |  |  | 				this.buildInfo.assets[name] = this.createSourceForAsset(name, content, sourceMap); | 
					
						
							| 
									
										
										
										
											2017-02-11 12:32:48 +08:00
										 |  |  | 			}, | 
					
						
							| 
									
										
										
										
											2017-09-14 15:00:22 +08:00
										 |  |  | 			rootContext: options.context, | 
					
						
							| 
									
										
										
										
											2017-02-11 12:32:48 +08:00
										 |  |  | 			webpack: true, | 
					
						
							|  |  |  | 			sourceMap: !!this.useSourceMap, | 
					
						
							|  |  |  | 			_module: this, | 
					
						
							|  |  |  | 			_compilation: compilation, | 
					
						
							|  |  |  | 			_compiler: compilation.compiler, | 
					
						
							|  |  |  | 			fs: fs, | 
					
						
							| 
									
										
										
										
											2017-02-11 11:16:18 +08:00
										 |  |  | 		}; | 
					
						
							| 
									
										
										
										
											2017-02-11 12:32:48 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-27 22:27:30 +08:00
										 |  |  | 		compilation.hooks.normalModuleLoader.call(loaderContext, this); | 
					
						
							| 
									
										
										
										
											2017-02-11 11:16:18 +08:00
										 |  |  | 		if(options.loader) | 
					
						
							| 
									
										
										
										
											2017-02-11 12:32:48 +08:00
										 |  |  | 			Object.assign(loaderContext, options.loader); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		return loaderContext; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-11 14:07:18 +08:00
										 |  |  | 	createSource(source, resourceBuffer, sourceMap) { | 
					
						
							| 
									
										
										
										
											2017-02-11 12:57:52 +08:00
										 |  |  | 		// if there is no identifier return raw source
 | 
					
						
							|  |  |  | 		if(!this.identifier) { | 
					
						
							|  |  |  | 			return new RawSource(source); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		// from here on we assume we have an identifier
 | 
					
						
							|  |  |  | 		const identifier = this.identifier(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if(this.lineToLine && resourceBuffer) { | 
					
						
							|  |  |  | 			return new LineToLineMappedSource( | 
					
						
							|  |  |  | 				source, identifier, asString(resourceBuffer)); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if(this.useSourceMap && sourceMap) { | 
					
						
							|  |  |  | 			return new SourceMapSource(source, identifier, sourceMap); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-10-30 20:56:57 +08:00
										 |  |  | 		if(Buffer.isBuffer(source)) { | 
					
						
							|  |  |  | 			return new RawSource(source); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-11 12:57:52 +08:00
										 |  |  | 		return new OriginalSource(source, identifier); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-11 12:32:48 +08:00
										 |  |  | 	doBuild(options, compilation, resolver, fs, callback) { | 
					
						
							|  |  |  | 		const loaderContext = this.createLoaderContext(resolver, options, compilation, fs); | 
					
						
							| 
									
										
										
										
											2013-01-31 01:49:25 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-11 11:16:18 +08:00
										 |  |  | 		runLoaders({ | 
					
						
							|  |  |  | 			resource: this.resource, | 
					
						
							|  |  |  | 			loaders: this.loaders, | 
					
						
							|  |  |  | 			context: loaderContext, | 
					
						
							|  |  |  | 			readResource: fs.readFile.bind(fs) | 
					
						
							| 
									
										
										
										
											2017-02-11 12:59:08 +08:00
										 |  |  | 		}, (err, result) => { | 
					
						
							| 
									
										
										
										
											2017-02-11 11:16:18 +08:00
										 |  |  | 			if(result) { | 
					
						
							| 
									
										
										
										
											2017-12-06 19:09:17 +08:00
										 |  |  | 				this.buildInfo.cacheable = result.cacheable; | 
					
						
							|  |  |  | 				this.buildInfo.fileDependencies = new Set(result.fileDependencies); | 
					
						
							|  |  |  | 				this.buildInfo.contextDependencies = new Set(result.contextDependencies); | 
					
						
							| 
									
										
										
										
											2017-02-11 11:16:18 +08:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2017-02-11 13:10:07 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-11 11:16:18 +08:00
										 |  |  | 			if(err) { | 
					
						
							| 
									
										
										
										
											2017-02-13 18:38:55 +08:00
										 |  |  | 				const error = new ModuleBuildError(this, err); | 
					
						
							|  |  |  | 				return callback(error); | 
					
						
							| 
									
										
										
										
											2014-02-04 19:21:01 +08:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2016-07-03 19:13:01 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-11 11:16:18 +08:00
										 |  |  | 			const resourceBuffer = result.resourceBuffer; | 
					
						
							| 
									
										
										
										
											2017-02-11 12:59:35 +08:00
										 |  |  | 			const source = result.result[0]; | 
					
						
							| 
									
										
										
										
											2017-11-03 18:12:45 +08:00
										 |  |  | 			const sourceMap = result.result.length >= 1 ? result.result[1] : null; | 
					
						
							|  |  |  | 			const extraInfo = result.result.length >= 2 ? result.result[2] : null; | 
					
						
							| 
									
										
										
										
											2013-01-31 01:49:25 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-11 11:16:18 +08:00
										 |  |  | 			if(!Buffer.isBuffer(source) && typeof source !== "string") { | 
					
						
							| 
									
										
										
										
											2017-02-13 18:38:55 +08:00
										 |  |  | 				const error = new ModuleBuildError(this, new Error("Final loader didn't return a Buffer or String")); | 
					
						
							|  |  |  | 				return callback(error); | 
					
						
							| 
									
										
										
										
											2017-02-11 11:16:18 +08:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2017-02-11 12:57:52 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-10-30 20:56:57 +08:00
										 |  |  | 			this._source = this.createSource(this.binary ? asBuffer(source) : asString(source), resourceBuffer, sourceMap); | 
					
						
							| 
									
										
										
										
											2017-11-03 18:12:45 +08:00
										 |  |  | 			this._ast = typeof extraInfo === "object" && extraInfo !== null && extraInfo.webpackAST !== undefined ? extraInfo.webpackAST : null; | 
					
						
							| 
									
										
										
										
											2017-02-11 11:16:18 +08:00
										 |  |  | 			return callback(); | 
					
						
							|  |  |  | 		}); | 
					
						
							| 
									
										
										
										
											2014-05-17 06:31:52 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-07-13 06:20:09 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-13 18:38:55 +08:00
										 |  |  | 	markModuleAsErrored(error) { | 
					
						
							| 
									
										
										
										
											2017-12-07 00:26:02 +08:00
										 |  |  | 		// Restore build meta from successfull build to keep importing state
 | 
					
						
							|  |  |  | 		this.buildMeta = Object.assign({}, this._lastSuccessfulBuildMeta); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-13 18:38:55 +08:00
										 |  |  | 		this.error = error; | 
					
						
							|  |  |  | 		this.errors.push(this.error); | 
					
						
							|  |  |  | 		this._source = new RawSource("throw new Error(" + JSON.stringify(this.error.message) + ");"); | 
					
						
							| 
									
										
										
										
											2017-11-03 18:12:45 +08:00
										 |  |  | 		this._ast = null; | 
					
						
							| 
									
										
										
										
											2017-02-11 11:41:26 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-14 18:14:57 +08:00
										 |  |  | 	applyNoParseRule(rule, content) { | 
					
						
							| 
									
										
										
										
											2017-02-11 13:59:58 +08:00
										 |  |  | 		// must start with "rule" if rule is a string
 | 
					
						
							|  |  |  | 		if(typeof rule === "string") { | 
					
						
							| 
									
										
										
										
											2017-02-14 18:14:57 +08:00
										 |  |  | 			return content.indexOf(rule) === 0; | 
					
						
							| 
									
										
										
										
											2017-02-11 13:59:58 +08:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2017-06-03 08:28:54 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		if(typeof rule === "function") { | 
					
						
							|  |  |  | 			return rule(content); | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2017-02-11 13:59:58 +08:00
										 |  |  | 		// we assume rule is a regexp
 | 
					
						
							| 
									
										
										
										
											2017-02-14 18:14:57 +08:00
										 |  |  | 		return rule.test(content); | 
					
						
							| 
									
										
										
										
											2017-02-11 13:59:58 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// check if module should not be parsed
 | 
					
						
							|  |  |  | 	// returns "true" if the module should !not! be parsed
 | 
					
						
							|  |  |  | 	// returns "false" if the module !must! be parsed
 | 
					
						
							| 
									
										
										
										
											2017-02-16 05:01:09 +08:00
										 |  |  | 	shouldPreventParsing(noParseRule, request) { | 
					
						
							| 
									
										
										
										
											2017-02-11 13:59:58 +08:00
										 |  |  | 		// if no noParseRule exists, return false
 | 
					
						
							|  |  |  | 		// the module !must! be parsed.
 | 
					
						
							|  |  |  | 		if(!noParseRule) { | 
					
						
							|  |  |  | 			return false; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		// we only have one rule to check
 | 
					
						
							|  |  |  | 		if(!Array.isArray(noParseRule)) { | 
					
						
							|  |  |  | 			// returns "true" if the module is !not! to be parsed
 | 
					
						
							|  |  |  | 			return this.applyNoParseRule(noParseRule, request); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		for(let i = 0; i < noParseRule.length; i++) { | 
					
						
							|  |  |  | 			const rule = noParseRule[i]; | 
					
						
							|  |  |  | 			// early exit on first truthy match
 | 
					
						
							|  |  |  | 			// this module is !not! to be parsed
 | 
					
						
							|  |  |  | 			if(this.applyNoParseRule(rule, request)) { | 
					
						
							|  |  |  | 				return true; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		// no match found, so this module !should! be parsed
 | 
					
						
							|  |  |  | 		return false; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-11 11:16:18 +08:00
										 |  |  | 	build(options, compilation, resolver, fs, callback) { | 
					
						
							| 
									
										
										
										
											2017-05-04 10:19:54 +08:00
										 |  |  | 		this.buildTimestamp = Date.now(); | 
					
						
							| 
									
										
										
										
											2017-02-11 11:16:18 +08:00
										 |  |  | 		this.built = true; | 
					
						
							|  |  |  | 		this._source = null; | 
					
						
							| 
									
										
										
										
											2017-11-03 18:12:45 +08:00
										 |  |  | 		this._ast = null; | 
					
						
							| 
									
										
										
										
											2017-02-11 11:16:18 +08:00
										 |  |  | 		this.error = null; | 
					
						
							|  |  |  | 		this.errors.length = 0; | 
					
						
							|  |  |  | 		this.warnings.length = 0; | 
					
						
							| 
									
										
										
										
											2017-12-06 19:09:17 +08:00
										 |  |  | 		this.buildMeta = {}; | 
					
						
							|  |  |  | 		this.buildInfo = { | 
					
						
							|  |  |  | 			cacheable: false, | 
					
						
							|  |  |  | 			fileDependencies: new Set(), | 
					
						
							|  |  |  | 			contextDependencies: new Set(), | 
					
						
							|  |  |  | 		}; | 
					
						
							| 
									
										
										
										
											2016-06-21 03:46:27 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-11 11:16:18 +08:00
										 |  |  | 		return this.doBuild(options, compilation, resolver, fs, (err) => { | 
					
						
							| 
									
										
										
										
											2017-12-01 18:07:23 +08:00
										 |  |  | 			this._cachedSource = undefined; | 
					
						
							|  |  |  | 			this._cachedSourceHash = undefined; | 
					
						
							| 
									
										
										
										
											2017-02-11 13:59:58 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			// if we have an error mark module as failed and exit
 | 
					
						
							| 
									
										
										
										
											2017-02-11 11:41:26 +08:00
										 |  |  | 			if(err) { | 
					
						
							| 
									
										
										
										
											2017-02-13 18:38:55 +08:00
										 |  |  | 				this.markModuleAsErrored(err); | 
					
						
							| 
									
										
										
										
											2017-02-11 11:41:26 +08:00
										 |  |  | 				return callback(); | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2017-02-11 13:59:58 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			// check if this module should !not! be parsed.
 | 
					
						
							|  |  |  | 			// if so, exit here;
 | 
					
						
							|  |  |  | 			const noParseRule = options.module && options.module.noParse; | 
					
						
							| 
									
										
										
										
											2017-02-16 05:01:09 +08:00
										 |  |  | 			if(this.shouldPreventParsing(noParseRule, this.request)) { | 
					
						
							| 
									
										
										
										
											2017-02-11 13:59:58 +08:00
										 |  |  | 				return callback(); | 
					
						
							| 
									
										
										
										
											2017-02-11 11:16:18 +08:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2017-02-11 13:59:58 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-14 08:21:44 +08:00
										 |  |  | 			const handleParseError = e => { | 
					
						
							|  |  |  | 				const source = this._source.source(); | 
					
						
							|  |  |  | 				const error = new ModuleParseError(this, source, e); | 
					
						
							|  |  |  | 				this.markModuleAsErrored(error); | 
					
						
							|  |  |  | 				return callback(); | 
					
						
							|  |  |  | 			}; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			const handleParseResult = result => { | 
					
						
							|  |  |  | 				this._lastSuccessfulBuildMeta = this.buildMeta; | 
					
						
							|  |  |  | 				return callback(); | 
					
						
							|  |  |  | 			}; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-11 11:16:18 +08:00
										 |  |  | 			try { | 
					
						
							| 
									
										
										
										
											2017-12-14 08:21:44 +08:00
										 |  |  | 				const result = this.parser.parse(this._ast || this._source.source(), { | 
					
						
							| 
									
										
										
										
											2017-02-11 11:16:18 +08:00
										 |  |  | 					current: this, | 
					
						
							|  |  |  | 					module: this, | 
					
						
							|  |  |  | 					compilation: compilation, | 
					
						
							|  |  |  | 					options: options | 
					
						
							| 
									
										
										
										
											2017-12-14 08:21:44 +08:00
										 |  |  | 				}, (err, result) => { | 
					
						
							|  |  |  | 					if(err) { | 
					
						
							|  |  |  | 						handleParseError(err); | 
					
						
							|  |  |  | 					} else { | 
					
						
							|  |  |  | 						handleParseResult(result); | 
					
						
							|  |  |  | 					} | 
					
						
							| 
									
										
										
										
											2017-02-11 11:16:18 +08:00
										 |  |  | 				}); | 
					
						
							| 
									
										
										
										
											2017-12-14 08:21:44 +08:00
										 |  |  | 				if(result !== undefined) { | 
					
						
							|  |  |  | 					// parse is sync
 | 
					
						
							|  |  |  | 					handleParseResult(result); | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2017-02-11 11:16:18 +08:00
										 |  |  | 			} catch(e) { | 
					
						
							| 
									
										
										
										
											2017-12-14 08:21:44 +08:00
										 |  |  | 				handleParseError(e); | 
					
						
							| 
									
										
										
										
											2017-02-11 11:16:18 +08:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2015-07-13 06:20:09 +08:00
										 |  |  | 		}); | 
					
						
							| 
									
										
										
										
											2013-01-31 01:49:25 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-07-13 06:20:09 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-10 19:15:14 +08:00
										 |  |  | 	getHashDigest(dependencyTemplates) { | 
					
						
							| 
									
										
										
										
											2017-07-14 18:50:39 +08:00
										 |  |  | 		let dtHash = dependencyTemplatesHashMap.get("hash"); | 
					
						
							| 
									
										
										
										
											2017-12-01 18:07:23 +08:00
										 |  |  | 		return `${this.hash}-${dtHash}`; | 
					
						
							| 
									
										
										
										
											2017-02-13 19:09:16 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-02-11 11:16:18 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-07 17:31:00 +08:00
										 |  |  | 	sourceDependency(dependency, dependencyTemplates, source, runtimeTemplate) { | 
					
						
							| 
									
										
										
										
											2017-02-13 19:09:16 +08:00
										 |  |  | 		const template = dependencyTemplates.get(dependency.constructor); | 
					
						
							|  |  |  | 		if(!template) throw new Error("No template for dependency: " + dependency.constructor.name); | 
					
						
							| 
									
										
										
										
											2017-12-07 17:31:00 +08:00
										 |  |  | 		template.apply(dependency, source, runtimeTemplate, dependencyTemplates); | 
					
						
							| 
									
										
										
										
											2017-02-13 19:09:16 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-07-13 06:20:09 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-07 17:31:00 +08:00
										 |  |  | 	sourceVariables(variable, availableVars, dependencyTemplates, runtimeTemplate) { | 
					
						
							| 
									
										
										
										
											2017-02-13 19:09:16 +08:00
										 |  |  | 		const name = variable.name; | 
					
						
							| 
									
										
										
										
											2017-12-07 17:31:00 +08:00
										 |  |  | 		const expr = variable.expressionSource(dependencyTemplates, runtimeTemplate); | 
					
						
							| 
									
										
										
										
											2013-02-26 19:36:34 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-13 19:09:16 +08:00
										 |  |  | 		if(availableVars.some(v => v.name === name && v.expression.source() === expr.source())) { | 
					
						
							|  |  |  | 			return; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2017-02-13 20:13:07 +08:00
										 |  |  | 		return { | 
					
						
							| 
									
										
										
										
											2017-02-13 19:09:16 +08:00
										 |  |  | 			name: name, | 
					
						
							|  |  |  | 			expression: expr | 
					
						
							| 
									
										
										
										
											2017-02-13 20:13:07 +08:00
										 |  |  | 		}; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-16 05:01:09 +08:00
										 |  |  | 	/* | 
					
						
							|  |  |  | 	 * creates the start part of a IIFE around the module to inject a variable name | 
					
						
							|  |  |  | 	 * (function(...){   <- this part | 
					
						
							|  |  |  | 	 * }.call(...)) | 
					
						
							|  |  |  | 	 */ | 
					
						
							| 
									
										
										
										
											2017-02-13 20:13:07 +08:00
										 |  |  | 	variableInjectionFunctionWrapperStartCode(varNames) { | 
					
						
							|  |  |  | 		const args = varNames.join(", "); | 
					
						
							| 
									
										
										
										
											2017-02-16 05:01:09 +08:00
										 |  |  | 		return `/* WEBPACK VAR INJECTION */(function(${args}) {`; | 
					
						
							| 
									
										
										
										
											2017-02-13 20:13:07 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	contextArgument(block) { | 
					
						
							|  |  |  | 		if(this === block) { | 
					
						
							| 
									
										
										
										
											2017-11-12 01:48:29 +08:00
										 |  |  | 			return this.exportsArgument; | 
					
						
							| 
									
										
										
										
											2017-02-13 20:13:07 +08:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		return "this"; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-02-16 05:01:09 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	/* | 
					
						
							|  |  |  | 	 * creates the end part of a IIFE around the module to inject a variable name | 
					
						
							|  |  |  | 	 * (function(...){ | 
					
						
							|  |  |  | 	 * }.call(...))   <- this part | 
					
						
							|  |  |  | 	 */ | 
					
						
							| 
									
										
										
										
											2017-02-13 20:13:07 +08:00
										 |  |  | 	variableInjectionFunctionWrapperEndCode(varExpressions, block) { | 
					
						
							|  |  |  | 		const firstParam = this.contextArgument(block); | 
					
						
							|  |  |  | 		const furtherParams = varExpressions.map(e => e.source()).join(", "); | 
					
						
							| 
									
										
										
										
											2017-02-16 05:01:09 +08:00
										 |  |  | 		return `}.call(${firstParam}, ${furtherParams}))`; | 
					
						
							| 
									
										
										
										
											2017-02-13 19:09:16 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-13 21:16:54 +08:00
										 |  |  | 	splitVariablesInUniqueNamedChunks(vars) { | 
					
						
							| 
									
										
										
										
											2017-02-16 16:31:58 +08:00
										 |  |  | 		const startState = [ | 
					
						
							|  |  |  | 			[] | 
					
						
							|  |  |  | 		]; | 
					
						
							| 
									
										
										
										
											2017-02-16 05:01:09 +08:00
										 |  |  | 		return vars.reduce((chunks, variable) => { | 
					
						
							|  |  |  | 			const current = chunks[chunks.length - 1]; | 
					
						
							|  |  |  | 			// check if variable with same name exists already
 | 
					
						
							|  |  |  | 			// if so create a new chunk of variables.
 | 
					
						
							|  |  |  | 			const variableNameAlreadyExists = current.some(v => v.name === variable.name); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			if(variableNameAlreadyExists) { | 
					
						
							|  |  |  | 				// start new chunk with current variable
 | 
					
						
							|  |  |  | 				chunks.push([variable]); | 
					
						
							| 
									
										
										
										
											2017-02-13 21:16:54 +08:00
										 |  |  | 			} else { | 
					
						
							| 
									
										
										
										
											2017-02-16 05:01:09 +08:00
										 |  |  | 				// else add it to current chunk
 | 
					
						
							|  |  |  | 				current.push(variable); | 
					
						
							| 
									
										
										
										
											2017-02-13 21:16:54 +08:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2017-02-16 05:01:09 +08:00
										 |  |  | 			return chunks; | 
					
						
							| 
									
										
										
										
											2017-02-16 16:31:58 +08:00
										 |  |  | 		}, startState); | 
					
						
							| 
									
										
										
										
											2017-02-13 21:16:54 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-07 17:31:00 +08:00
										 |  |  | 	sourceBlock(block, availableVars, dependencyTemplates, source, runtimeTemplate) { | 
					
						
							| 
									
										
										
										
											2017-02-13 19:09:16 +08:00
										 |  |  | 		block.dependencies.forEach((dependency) => this.sourceDependency( | 
					
						
							| 
									
										
										
										
											2017-12-07 17:31:00 +08:00
										 |  |  | 			dependency, dependencyTemplates, source, runtimeTemplate)); | 
					
						
							| 
									
										
										
										
											2017-02-13 19:09:16 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-13 21:16:54 +08:00
										 |  |  | 		/** | 
					
						
							|  |  |  | 		 * Get the variables of all blocks that we need to inject. | 
					
						
							|  |  |  | 		 * These will contain the variable name and its expression. | 
					
						
							|  |  |  | 		 * The name will be added as a paramter in a IIFE the expression as its value. | 
					
						
							|  |  |  | 		 */ | 
					
						
							| 
									
										
										
										
											2017-07-18 10:42:57 +08:00
										 |  |  | 		const vars = block.variables.reduce((result, value) => { | 
					
						
							|  |  |  | 			const variable = this.sourceVariables( | 
					
						
							| 
									
										
										
										
											2017-12-07 17:31:00 +08:00
										 |  |  | 				value, availableVars, dependencyTemplates, runtimeTemplate); | 
					
						
							| 
									
										
										
										
											2017-07-18 10:42:57 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			if(variable) { | 
					
						
							|  |  |  | 				result.push(variable); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			return result; | 
					
						
							|  |  |  | 		}, []); | 
					
						
							| 
									
										
										
										
											2017-02-13 21:16:54 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-16 16:31:58 +08:00
										 |  |  | 		/** | 
					
						
							|  |  |  | 		 * if we actually have variables | 
					
						
							|  |  |  | 		 * this is important as how #splitVariablesInUniqueNamedChunks works | 
					
						
							|  |  |  | 		 * it will always return an array in an array which would lead to a IIFE wrapper around | 
					
						
							|  |  |  | 		 * a module if we do this with an empty vars array. | 
					
						
							|  |  |  | 		 */ | 
					
						
							| 
									
										
										
										
											2017-02-13 20:13:07 +08:00
										 |  |  | 		if(vars.length > 0) { | 
					
						
							| 
									
										
										
										
											2017-02-13 21:16:54 +08:00
										 |  |  | 			/** | 
					
						
							|  |  |  | 			 * Split all variables up into chunks of unique names. | 
					
						
							|  |  |  | 			 * e.g. imagine you have the following variable names that need to be injected: | 
					
						
							| 
									
										
										
										
											2017-02-16 05:01:09 +08:00
										 |  |  | 			 * [foo, bar, baz, foo, some, more] | 
					
						
							| 
									
										
										
										
											2017-02-13 21:16:54 +08:00
										 |  |  | 			 * we can not inject "foo" twice, therefore we just make two IIFEs like so: | 
					
						
							|  |  |  | 			 * (function(foo, bar, baz){ | 
					
						
							| 
									
										
										
										
											2017-02-16 05:01:09 +08:00
										 |  |  | 			 *   (function(foo, some, more){ | 
					
						
							| 
									
										
										
										
											2017-02-13 21:16:54 +08:00
										 |  |  | 			 *     ... | 
					
						
							|  |  |  | 			 *   }(...)); | 
					
						
							|  |  |  | 			 * }(...)); | 
					
						
							|  |  |  | 			 * | 
					
						
							|  |  |  | 			 * "splitVariablesInUniqueNamedChunks" splits the variables shown above up to this: | 
					
						
							| 
									
										
										
										
											2017-02-16 05:01:09 +08:00
										 |  |  | 			 * [[foo, bar, baz], [foo, some, more]] | 
					
						
							| 
									
										
										
										
											2017-02-13 21:16:54 +08:00
										 |  |  | 			 */ | 
					
						
							|  |  |  | 			const injectionVariableChunks = this.splitVariablesInUniqueNamedChunks(vars); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			// create all the beginnings of IIFEs
 | 
					
						
							| 
									
										
										
										
											2017-07-18 10:42:57 +08:00
										 |  |  | 			const functionWrapperStarts = injectionVariableChunks.map((variableChunk) => { | 
					
						
							|  |  |  | 				return this.variableInjectionFunctionWrapperStartCode( | 
					
						
							|  |  |  | 					variableChunk.map(variable => variable.name) | 
					
						
							|  |  |  | 				); | 
					
						
							|  |  |  | 			}); | 
					
						
							| 
									
										
										
										
											2017-02-13 21:16:54 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			// and all the ends
 | 
					
						
							| 
									
										
										
										
											2017-07-18 10:42:57 +08:00
										 |  |  | 			const functionWrapperEnds = injectionVariableChunks.map((variableChunk) => { | 
					
						
							|  |  |  | 				return this.variableInjectionFunctionWrapperEndCode( | 
					
						
							|  |  |  | 					variableChunk.map(variable => variable.expression), block | 
					
						
							|  |  |  | 				); | 
					
						
							|  |  |  | 			}); | 
					
						
							| 
									
										
										
										
											2017-02-13 21:16:54 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			// join them to one big string
 | 
					
						
							|  |  |  | 			const varStartCode = functionWrapperStarts.join(""); | 
					
						
							| 
									
										
										
										
											2017-07-18 10:42:57 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-13 21:16:54 +08:00
										 |  |  | 			// reverse the ends first before joining them, as the last added must be the inner most
 | 
					
						
							|  |  |  | 			const varEndCode = functionWrapperEnds.reverse().join(""); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			// if we have anything, add it to the source
 | 
					
						
							| 
									
										
										
										
											2017-02-13 20:13:07 +08:00
										 |  |  | 			if(varStartCode && varEndCode) { | 
					
						
							|  |  |  | 				const start = block.range ? block.range[0] : -10; | 
					
						
							|  |  |  | 				const end = block.range ? block.range[1] : (this._source.size() + 1); | 
					
						
							|  |  |  | 				source.insert(start + 0.5, varStartCode); | 
					
						
							|  |  |  | 				source.insert(end + 0.5, "\n/* WEBPACK VAR INJECTION */" + varEndCode); | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2013-01-31 01:49:25 +08:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2017-07-18 10:42:57 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		block.blocks.forEach((block) => | 
					
						
							|  |  |  | 			this.sourceBlock( | 
					
						
							|  |  |  | 				block, | 
					
						
							|  |  |  | 				availableVars.concat(vars), | 
					
						
							|  |  |  | 				dependencyTemplates, | 
					
						
							|  |  |  | 				source, | 
					
						
							| 
									
										
										
										
											2017-12-07 17:31:00 +08:00
										 |  |  | 				runtimeTemplate | 
					
						
							| 
									
										
										
										
											2017-07-18 10:42:57 +08:00
										 |  |  | 			) | 
					
						
							|  |  |  | 		); | 
					
						
							| 
									
										
										
										
											2017-02-13 19:09:16 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-02-11 11:16:18 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-07 17:31:00 +08:00
										 |  |  | 	source(dependencyTemplates, runtimeTemplate) { | 
					
						
							| 
									
										
										
										
											2017-10-30 20:56:57 +08:00
										 |  |  | 		if(this.type.startsWith("javascript")) { | 
					
						
							|  |  |  | 			const hashDigest = this.getHashDigest(dependencyTemplates); | 
					
						
							| 
									
										
										
										
											2017-12-01 18:07:23 +08:00
										 |  |  | 			if(this._cachedSourceHash === hashDigest) { | 
					
						
							|  |  |  | 				// We can reuse the cached source
 | 
					
						
							|  |  |  | 				return this._cachedSource; | 
					
						
							| 
									
										
										
										
											2017-10-30 20:56:57 +08:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2017-02-13 19:09:16 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-10-30 20:56:57 +08:00
										 |  |  | 			if(!this._source) { | 
					
						
							|  |  |  | 				return new RawSource("throw new Error('No source available');"); | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2017-02-13 19:09:16 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-10-30 20:56:57 +08:00
										 |  |  | 			const source = new ReplaceSource(this._source); | 
					
						
							| 
									
										
										
										
											2017-02-16 05:01:09 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-07 17:31:00 +08:00
										 |  |  | 			this.sourceBlock(this, [], dependencyTemplates, source, runtimeTemplate); | 
					
						
							| 
									
										
										
										
											2017-12-01 18:07:23 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			const cachedSource = new CachedSource(source); | 
					
						
							|  |  |  | 			this._cachedSource = cachedSource; | 
					
						
							|  |  |  | 			this._cachedSourceHash = hashDigest; | 
					
						
							|  |  |  | 			return cachedSource; | 
					
						
							| 
									
										
										
										
											2017-10-30 20:56:57 +08:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		return this._source; | 
					
						
							| 
									
										
										
										
											2013-01-31 01:49:25 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-03 15:48:55 +08:00
										 |  |  | 	originalSource() { | 
					
						
							|  |  |  | 		return this._source; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-04-03 15:33:11 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-11 11:16:18 +08:00
										 |  |  | 	needRebuild(fileTimestamps, contextTimestamps) { | 
					
						
							| 
									
										
										
										
											2017-11-06 20:02:35 +08:00
										 |  |  | 		// always try to rebuild in case of an error
 | 
					
						
							|  |  |  | 		if(this.error) return true; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		// always rebuild when module is not cacheable
 | 
					
						
							| 
									
										
										
										
											2017-12-06 19:09:17 +08:00
										 |  |  | 		if(!this.buildInfo.cacheable) return true; | 
					
						
							| 
									
										
										
										
											2017-02-11 13:10:07 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 23:41:26 +08:00
										 |  |  | 		// Check timestamps of all dependencies
 | 
					
						
							|  |  |  | 		// Missing timestamp -> need rebuild
 | 
					
						
							|  |  |  | 		// Timestamp bigger than buildTimestamp -> need rebuild
 | 
					
						
							| 
									
										
										
										
											2017-12-06 19:09:17 +08:00
										 |  |  | 		for(const file of this.buildInfo.fileDependencies) { | 
					
						
							| 
									
										
										
										
											2017-11-06 23:41:26 +08:00
										 |  |  | 			const timestamp = fileTimestamps[file]; | 
					
						
							|  |  |  | 			if(!timestamp) return true; | 
					
						
							|  |  |  | 			if(timestamp >= this.buildTimestamp) return true; | 
					
						
							| 
									
										
										
										
											2017-02-11 13:10:07 +08:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2017-12-06 19:09:17 +08:00
										 |  |  | 		for(const file of this.buildInfo.contextDependencies) { | 
					
						
							| 
									
										
										
										
											2017-11-06 23:41:26 +08:00
										 |  |  | 			const timestamp = contextTimestamps[file]; | 
					
						
							|  |  |  | 			if(!timestamp) return true; | 
					
						
							|  |  |  | 			if(timestamp >= this.buildTimestamp) return true; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		// elsewise -> no rebuild needed
 | 
					
						
							|  |  |  | 		return false; | 
					
						
							| 
									
										
										
										
											2017-02-11 11:16:18 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2013-01-31 01:49:25 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-11 11:16:18 +08:00
										 |  |  | 	size() { | 
					
						
							|  |  |  | 		return this._source ? this._source.size() : -1; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-11 11:17:54 +08:00
										 |  |  | 	updateHashWithSource(hash) { | 
					
						
							|  |  |  | 		if(!this._source) { | 
					
						
							| 
									
										
										
										
											2017-02-11 11:16:18 +08:00
										 |  |  | 			hash.update("null"); | 
					
						
							| 
									
										
										
										
											2017-02-11 11:17:54 +08:00
										 |  |  | 			return; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		hash.update("source"); | 
					
						
							|  |  |  | 		this._source.updateHash(hash); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	updateHashWithMeta(hash) { | 
					
						
							| 
									
										
										
										
											2017-02-11 11:16:18 +08:00
										 |  |  | 		hash.update("meta"); | 
					
						
							| 
									
										
										
										
											2017-12-06 19:09:17 +08:00
										 |  |  | 		hash.update(JSON.stringify(this.buildMeta)); | 
					
						
							| 
									
										
										
										
											2017-02-11 11:17:54 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	updateHash(hash) { | 
					
						
							|  |  |  | 		this.updateHashWithSource(hash); | 
					
						
							|  |  |  | 		this.updateHashWithMeta(hash); | 
					
						
							| 
									
										
										
										
											2017-02-11 11:16:18 +08:00
										 |  |  | 		super.updateHash(hash); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2013-01-31 01:49:25 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-11 11:16:18 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | module.exports = NormalModule; |