| 
									
										
										
										
											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
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-22 19:05:58 +08:00
										 |  |  | const { | 
					
						
							|  |  |  | 	CachedSource, | 
					
						
							|  |  |  | 	LineToLineMappedSource, | 
					
						
							|  |  |  | 	OriginalSource, | 
					
						
							|  |  |  | 	RawSource, | 
					
						
							|  |  |  | 	SourceMapSource | 
					
						
							|  |  |  | } = require("webpack-sources"); | 
					
						
							|  |  |  | const { getContext, runLoaders } = require("loader-runner"); | 
					
						
							| 
									
										
										
										
											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"); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | const asString = buf => { | 
					
						
							|  |  |  | 	if (Buffer.isBuffer(buf)) { | 
					
						
							| 
									
										
										
										
											2016-01-04 04:42:56 +08:00
										 |  |  | 		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 => { | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 	if (!Buffer.isBuffer(str)) { | 
					
						
							| 
									
										
										
										
											2018-01-22 22:00:12 +08:00
										 |  |  | 		return Buffer.from(str, "utf-8"); | 
					
						
							| 
									
										
										
										
											2017-10-30 20:56:57 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	return str; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-08 18:32:05 +08:00
										 |  |  | const contextify = (context, request) => { | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 	return request | 
					
						
							|  |  |  | 		.split("!") | 
					
						
							|  |  |  | 		.map(r => { | 
					
						
							|  |  |  | 			const splitPath = r.split("?"); | 
					
						
							|  |  |  | 			splitPath[0] = path.relative(context, splitPath[0]); | 
					
						
							|  |  |  | 			if (path.sep === "\\") splitPath[0] = splitPath[0].replace(/\\/g, "/"); | 
					
						
							|  |  |  | 			if (splitPath[0].indexOf("../") !== 0) splitPath[0] = "./" + splitPath[0]; | 
					
						
							|  |  |  | 			return splitPath.join("?"); | 
					
						
							|  |  |  | 		}) | 
					
						
							|  |  |  | 		.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 { | 
					
						
							| 
									
										
										
										
											2018-01-24 06:09:26 +08:00
										 |  |  | 	constructor({ | 
					
						
							|  |  |  | 		type, | 
					
						
							|  |  |  | 		request, | 
					
						
							|  |  |  | 		userRequest, | 
					
						
							|  |  |  | 		rawRequest, | 
					
						
							|  |  |  | 		loaders, | 
					
						
							|  |  |  | 		resource, | 
					
						
							|  |  |  | 		parser, | 
					
						
							|  |  |  | 		generator, | 
					
						
							|  |  |  | 		resolveOptions | 
					
						
							|  |  |  | 	}) { | 
					
						
							| 
									
										
										
										
											2018-01-31 04:40:44 +08:00
										 |  |  | 		super(type, getContext(resource)); | 
					
						
							| 
									
										
										
										
											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; | 
					
						
							| 
									
										
										
										
											2018-01-24 06:09:26 +08:00
										 |  |  | 		this.generator = generator; | 
					
						
							| 
									
										
										
										
											2017-02-11 11:16:18 +08:00
										 |  |  | 		this.resource = resource; | 
					
						
							|  |  |  | 		this.loaders = loaders; | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +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("?"); | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 		if (idx >= 0) return this.resource.substr(0, idx); | 
					
						
							| 
									
										
										
										
											2017-02-11 11:16:18 +08:00
										 |  |  | 		return this.resource; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2013-01-31 01:49:25 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-28 22:19:15 +08:00
										 |  |  | 	updateCacheModule(module) { | 
					
						
							|  |  |  | 		this.userRequest = module.userRequest; | 
					
						
							|  |  |  | 		this.parser = module.parser; | 
					
						
							|  |  |  | 		this.generator = module.generator; | 
					
						
							|  |  |  | 		this.resource = module.resource; | 
					
						
							|  |  |  | 		this.loaders = module.loaders; | 
					
						
							|  |  |  | 		this.resolveOptions = module.resolveOptions; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-11 14:07:01 +08:00
										 |  |  | 	createSourceForAsset(name, content, sourceMap) { | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 		if (!sourceMap) { | 
					
						
							| 
									
										
										
										
											2017-02-11 14:07:01 +08:00
										 |  |  | 			return new RawSource(content); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 		if (typeof sourceMap === "string") { | 
					
						
							| 
									
										
										
										
											2017-02-11 14:07:01 +08:00
										 |  |  | 			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, | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 			emitWarning: warning => { | 
					
						
							|  |  |  | 				if (!(warning instanceof Error)) | 
					
						
							| 
									
										
										
										
											2017-03-22 20:00:57 +08:00
										 |  |  | 					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
										 |  |  | 			}, | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 			emitError: error => { | 
					
						
							|  |  |  | 				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-12-31 23:23:45 +08:00
										 |  |  | 				resolver.resolve({}, context, request, {}, callback); | 
					
						
							| 
									
										
										
										
											2017-02-11 11:16:18 +08:00
										 |  |  | 			}, | 
					
						
							| 
									
										
										
										
											2017-02-11 12:32:48 +08:00
										 |  |  | 			emitFile: (name, content, sourceMap) => { | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +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, | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 			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); | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 		if (options.loader) Object.assign(loaderContext, options.loader); | 
					
						
							| 
									
										
										
										
											2017-02-11 12:32:48 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		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
 | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 		if (!this.identifier) { | 
					
						
							| 
									
										
										
										
											2017-02-11 12:57:52 +08:00
										 |  |  | 			return new RawSource(source); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		// from here on we assume we have an identifier
 | 
					
						
							|  |  |  | 		const identifier = this.identifier(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 		if (this.lineToLine && resourceBuffer) { | 
					
						
							| 
									
										
										
										
											2017-02-11 12:57:52 +08:00
										 |  |  | 			return new LineToLineMappedSource( | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 				source, | 
					
						
							|  |  |  | 				identifier, | 
					
						
							|  |  |  | 				asString(resourceBuffer) | 
					
						
							|  |  |  | 			); | 
					
						
							| 
									
										
										
										
											2017-02-11 12:57:52 +08:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 		if (this.useSourceMap && sourceMap) { | 
					
						
							| 
									
										
										
										
											2017-02-11 12:57:52 +08:00
										 |  |  | 			return new SourceMapSource(source, identifier, sourceMap); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 		if (Buffer.isBuffer(source)) { | 
					
						
							| 
									
										
										
										
											2017-10-30 20:56:57 +08:00
										 |  |  | 			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) { | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 		const loaderContext = this.createLoaderContext( | 
					
						
							|  |  |  | 			resolver, | 
					
						
							|  |  |  | 			options, | 
					
						
							|  |  |  | 			compilation, | 
					
						
							|  |  |  | 			fs | 
					
						
							|  |  |  | 		); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		runLoaders( | 
					
						
							|  |  |  | 			{ | 
					
						
							|  |  |  | 				resource: this.resource, | 
					
						
							|  |  |  | 				loaders: this.loaders, | 
					
						
							|  |  |  | 				context: loaderContext, | 
					
						
							|  |  |  | 				readResource: fs.readFile.bind(fs) | 
					
						
							|  |  |  | 			}, | 
					
						
							|  |  |  | 			(err, result) => { | 
					
						
							|  |  |  | 				if (result) { | 
					
						
							|  |  |  | 					this.buildInfo.cacheable = result.cacheable; | 
					
						
							|  |  |  | 					this.buildInfo.fileDependencies = new Set(result.fileDependencies); | 
					
						
							|  |  |  | 					this.buildInfo.contextDependencies = new Set( | 
					
						
							|  |  |  | 						result.contextDependencies | 
					
						
							|  |  |  | 					); | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2017-02-11 13:10:07 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 				if (err) { | 
					
						
							|  |  |  | 					const error = new ModuleBuildError(this, err); | 
					
						
							|  |  |  | 					return callback(error); | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2016-07-03 19:13:01 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 				const resourceBuffer = result.resourceBuffer; | 
					
						
							|  |  |  | 				const source = result.result[0]; | 
					
						
							|  |  |  | 				const sourceMap = result.result.length >= 1 ? result.result[1] : null; | 
					
						
							|  |  |  | 				const extraInfo = result.result.length >= 2 ? result.result[2] : null; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				if (!Buffer.isBuffer(source) && typeof source !== "string") { | 
					
						
							|  |  |  | 					const error = new ModuleBuildError( | 
					
						
							|  |  |  | 						this, | 
					
						
							|  |  |  | 						new Error("Final loader didn't return a Buffer or String") | 
					
						
							|  |  |  | 					); | 
					
						
							|  |  |  | 					return callback(error); | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2013-01-31 01:49:25 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 				this._source = this.createSource( | 
					
						
							|  |  |  | 					this.binary ? asBuffer(source) : asString(source), | 
					
						
							|  |  |  | 					resourceBuffer, | 
					
						
							|  |  |  | 					sourceMap | 
					
						
							|  |  |  | 				); | 
					
						
							|  |  |  | 				this._ast = | 
					
						
							|  |  |  | 					typeof extraInfo === "object" && | 
					
						
							|  |  |  | 					extraInfo !== null && | 
					
						
							|  |  |  | 					extraInfo.webpackAST !== undefined | 
					
						
							|  |  |  | 						? extraInfo.webpackAST | 
					
						
							|  |  |  | 						: null; | 
					
						
							|  |  |  | 				return callback(); | 
					
						
							| 
									
										
										
										
											2017-02-11 11:16:18 +08:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 		); | 
					
						
							| 
									
										
										
										
											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) { | 
					
						
							| 
									
										
										
										
											2018-02-26 10:48:51 +08:00
										 |  |  | 		// Restore build meta from successful build to keep importing state
 | 
					
						
							| 
									
										
										
										
											2017-12-07 00:26:02 +08:00
										 |  |  | 		this.buildMeta = Object.assign({}, this._lastSuccessfulBuildMeta); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-13 18:38:55 +08:00
										 |  |  | 		this.error = error; | 
					
						
							|  |  |  | 		this.errors.push(this.error); | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 		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
 | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 		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
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 		if (typeof rule === "function") { | 
					
						
							| 
									
										
										
										
											2017-06-03 08:28:54 +08:00
										 |  |  | 			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.
 | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 		if (!noParseRule) { | 
					
						
							| 
									
										
										
										
											2017-02-11 13:59:58 +08:00
										 |  |  | 			return false; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		// we only have one rule to check
 | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 		if (!Array.isArray(noParseRule)) { | 
					
						
							| 
									
										
										
										
											2017-02-11 13:59:58 +08:00
										 |  |  | 			// returns "true" if the module is !not! to be parsed
 | 
					
						
							|  |  |  | 			return this.applyNoParseRule(noParseRule, request); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 		for (let i = 0; i < noParseRule.length; i++) { | 
					
						
							| 
									
										
										
										
											2017-02-11 13:59:58 +08:00
										 |  |  | 			const rule = noParseRule[i]; | 
					
						
							|  |  |  | 			// early exit on first truthy match
 | 
					
						
							|  |  |  | 			// this module is !not! to be parsed
 | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 			if (this.applyNoParseRule(rule, request)) { | 
					
						
							| 
									
										
										
										
											2017-02-11 13:59:58 +08:00
										 |  |  | 				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(), | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 			contextDependencies: new Set() | 
					
						
							| 
									
										
										
										
											2017-12-06 19:09:17 +08:00
										 |  |  | 		}; | 
					
						
							| 
									
										
										
										
											2016-06-21 03:46:27 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +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
 | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +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; | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +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 { | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 				const result = this.parser.parse( | 
					
						
							|  |  |  | 					this._ast || this._source.source(), | 
					
						
							|  |  |  | 					{ | 
					
						
							|  |  |  | 						current: this, | 
					
						
							|  |  |  | 						module: this, | 
					
						
							|  |  |  | 						compilation: compilation, | 
					
						
							|  |  |  | 						options: options | 
					
						
							|  |  |  | 					}, | 
					
						
							|  |  |  | 					(err, result) => { | 
					
						
							|  |  |  | 						if (err) { | 
					
						
							|  |  |  | 							handleParseError(err); | 
					
						
							|  |  |  | 						} else { | 
					
						
							|  |  |  | 							handleParseResult(result); | 
					
						
							|  |  |  | 						} | 
					
						
							| 
									
										
										
										
											2017-12-14 08:21:44 +08:00
										 |  |  | 					} | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 				); | 
					
						
							|  |  |  | 				if (result !== undefined) { | 
					
						
							| 
									
										
										
										
											2017-12-14 08:21:44 +08:00
										 |  |  | 					// parse is sync
 | 
					
						
							|  |  |  | 					handleParseResult(result); | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +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
										 |  |  | 	source(dependencyTemplates, runtimeTemplate) { | 
					
						
							| 
									
										
										
										
											2018-01-24 06:09:26 +08:00
										 |  |  | 		const hashDigest = this.getHashDigest(dependencyTemplates); | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 		if (this._cachedSourceHash === hashDigest) { | 
					
						
							| 
									
										
										
										
											2018-01-24 06:09:26 +08:00
										 |  |  | 			// We can reuse the cached source
 | 
					
						
							|  |  |  | 			return this._cachedSource; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2017-02-16 05:01:09 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 		const source = this.generator.generate( | 
					
						
							|  |  |  | 			this, | 
					
						
							|  |  |  | 			dependencyTemplates, | 
					
						
							|  |  |  | 			runtimeTemplate | 
					
						
							|  |  |  | 		); | 
					
						
							| 
									
										
										
										
											2017-12-01 18:07:23 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-24 06:09:26 +08:00
										 |  |  | 		const cachedSource = new CachedSource(source); | 
					
						
							|  |  |  | 		this._cachedSource = cachedSource; | 
					
						
							|  |  |  | 		this._cachedSourceHash = hashDigest; | 
					
						
							|  |  |  | 		return cachedSource; | 
					
						
							| 
									
										
										
										
											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
 | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 		if (this.error) return true; | 
					
						
							| 
									
										
										
										
											2017-11-06 20:02:35 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		// always rebuild when module is not cacheable
 | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +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
 | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 		for (const file of this.buildInfo.fileDependencies) { | 
					
						
							| 
									
										
										
										
											2018-01-23 15:30:22 +08:00
										 |  |  | 			const timestamp = fileTimestamps.get(file); | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 			if (!timestamp) return true; | 
					
						
							|  |  |  | 			if (timestamp >= this.buildTimestamp) return true; | 
					
						
							| 
									
										
										
										
											2017-02-11 13:10:07 +08:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 		for (const file of this.buildInfo.contextDependencies) { | 
					
						
							| 
									
										
										
										
											2018-01-23 15:30:22 +08:00
										 |  |  | 			const timestamp = contextTimestamps.get(file); | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 			if (!timestamp) return true; | 
					
						
							|  |  |  | 			if (timestamp >= this.buildTimestamp) return true; | 
					
						
							| 
									
										
										
										
											2017-11-06 23:41:26 +08:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		// 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) { | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 		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); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | module.exports = NormalModule; |