| 
									
										
										
										
											2013-01-31 01:49:25 +08:00
										 |  |  | /* | 
					
						
							| 
									
										
										
										
											2017-04-04 05:28:08 +08:00
										 |  |  |  MIT License http://www.opensource.org/licenses/mit-license.php
 | 
					
						
							|  |  |  |  Author Tobias Koppers @sokra | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | "use strict"; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-05 21:06:23 +08:00
										 |  |  | const asyncLib = require("async"); | 
					
						
							| 
									
										
										
										
											2017-11-28 16:54:24 +08:00
										 |  |  | const Tapable = require("tapable").Tapable; | 
					
						
							|  |  |  | const AsyncSeriesWaterfallHook = require("tapable").AsyncSeriesWaterfallHook; | 
					
						
							|  |  |  | const SyncWaterfallHook = require("tapable").SyncWaterfallHook; | 
					
						
							|  |  |  | const SyncBailHook = require("tapable").SyncBailHook; | 
					
						
							|  |  |  | const SyncHook = require("tapable").SyncHook; | 
					
						
							|  |  |  | const HookMap = require("tapable").HookMap; | 
					
						
							| 
									
										
										
										
											2017-04-04 05:28:08 +08:00
										 |  |  | const NormalModule = require("./NormalModule"); | 
					
						
							|  |  |  | const RawModule = require("./RawModule"); | 
					
						
							|  |  |  | const RuleSet = require("./RuleSet"); | 
					
						
							| 
									
										
										
										
											2017-11-17 21:26:23 +08:00
										 |  |  | const cachedMerge = require("./util/cachedMerge"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | const EMPTY_RESOLVE_OPTIONS = {}; | 
					
						
							| 
									
										
										
										
											2016-09-14 18:04:42 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-08 18:32:05 +08:00
										 |  |  | const loaderToIdent = data => { | 
					
						
							| 
									
										
										
										
											2016-09-14 18:04:42 +08:00
										 |  |  | 	if(!data.options) | 
					
						
							|  |  |  | 		return data.loader; | 
					
						
							|  |  |  | 	if(typeof data.options === "string") | 
					
						
							|  |  |  | 		return data.loader + "?" + data.options; | 
					
						
							|  |  |  | 	if(typeof data.options !== "object") | 
					
						
							|  |  |  | 		throw new Error("loader options must be string or object"); | 
					
						
							| 
									
										
										
										
											2017-01-18 05:26:38 +08:00
										 |  |  | 	if(data.ident) | 
					
						
							|  |  |  | 		return data.loader + "??" + data.ident; | 
					
						
							| 
									
										
										
										
											2016-09-14 18:04:42 +08:00
										 |  |  | 	return data.loader + "?" + JSON.stringify(data.options); | 
					
						
							| 
									
										
										
										
											2017-11-08 18:32:05 +08:00
										 |  |  | }; | 
					
						
							| 
									
										
										
										
											2013-01-31 01:49:25 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-08 18:32:05 +08:00
										 |  |  | const identToLoaderRequest = resultString => { | 
					
						
							| 
									
										
										
										
											2017-04-04 16:26:16 +08:00
										 |  |  | 	const idx = resultString.indexOf("?"); | 
					
						
							| 
									
										
										
										
											2017-04-04 05:28:08 +08:00
										 |  |  | 	let options; | 
					
						
							| 
									
										
										
										
											2016-12-08 23:57:47 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if(idx >= 0) { | 
					
						
							|  |  |  | 		options = resultString.substr(idx + 1); | 
					
						
							|  |  |  | 		resultString = resultString.substr(0, idx); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		return { | 
					
						
							|  |  |  | 			loader: resultString, | 
					
						
							| 
									
										
										
										
											2017-04-04 05:28:08 +08:00
										 |  |  | 			options | 
					
						
							| 
									
										
										
										
											2016-12-08 23:57:47 +08:00
										 |  |  | 		}; | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 		return { | 
					
						
							|  |  |  | 			loader: resultString | 
					
						
							| 
									
										
										
										
											2017-01-11 17:51:58 +08:00
										 |  |  | 		}; | 
					
						
							| 
									
										
										
										
											2016-12-08 23:57:47 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-11-08 18:32:05 +08:00
										 |  |  | }; | 
					
						
							| 
									
										
										
										
											2016-12-08 23:57:47 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-04 05:28:08 +08:00
										 |  |  | class NormalModuleFactory extends Tapable { | 
					
						
							| 
									
										
										
										
											2017-11-17 21:26:23 +08:00
										 |  |  | 	constructor(context, resolverFactory, options) { | 
					
						
							| 
									
										
										
										
											2017-04-04 05:28:08 +08:00
										 |  |  | 		super(); | 
					
						
							| 
									
										
										
										
											2017-11-28 16:54:24 +08:00
										 |  |  | 		this.hooks = { | 
					
						
							|  |  |  | 			resolver: new SyncWaterfallHook(["resolver"]), | 
					
						
							|  |  |  | 			factory: new SyncWaterfallHook(["factory"]), | 
					
						
							|  |  |  | 			beforeResolve: new AsyncSeriesWaterfallHook(["data"]), | 
					
						
							|  |  |  | 			afterResolve: new AsyncSeriesWaterfallHook(["data"]), | 
					
						
							|  |  |  | 			createModule: new SyncBailHook(["data"]), | 
					
						
							|  |  |  | 			module: new SyncWaterfallHook(["module", "data"]), | 
					
						
							|  |  |  | 			createParser: new HookMap(() => new SyncBailHook(["parserOptions"])), | 
					
						
							|  |  |  | 			parser: new HookMap(() => new SyncHook(["parser", "parserOptions"])), | 
					
						
							|  |  |  | 		}; | 
					
						
							|  |  |  | 		this._pluginCompat.tap("NormalModuleFactory", options => { | 
					
						
							|  |  |  | 			switch(options.name) { | 
					
						
							|  |  |  | 				case "before-resolve": | 
					
						
							|  |  |  | 				case "after-resolve": | 
					
						
							|  |  |  | 					options.async = true; | 
					
						
							|  |  |  | 					break; | 
					
						
							|  |  |  | 				case "parser": | 
					
						
							|  |  |  | 					this.hooks.parser.for("javascript/auto").tap(options.fn.name || "unnamed compat plugin", options.fn); | 
					
						
							|  |  |  | 					return true; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			let match; | 
					
						
							|  |  |  | 			match = /^parser (.+)$/.exec(options.name); | 
					
						
							|  |  |  | 			if(match) { | 
					
						
							|  |  |  | 				this.hooks.parser.for(match[1]).tap(options.fn.name || "unnamed compat plugin", options.fn.bind(this)); | 
					
						
							|  |  |  | 				return true; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			match = /^create-parser (.+)$/.exec(options.name); | 
					
						
							|  |  |  | 			if(match) { | 
					
						
							|  |  |  | 				this.hooks.createParser.for(match[1]).tap(options.fn.name || "unnamed compat plugin", options.fn.bind(this)); | 
					
						
							|  |  |  | 				return true; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		}); | 
					
						
							| 
									
										
										
										
											2017-11-17 21:26:23 +08:00
										 |  |  | 		this.resolverFactory = resolverFactory; | 
					
						
							|  |  |  | 		this.ruleSet = new RuleSet(options.defaultRules.concat(options.rules)); | 
					
						
							| 
									
										
										
										
											2017-04-04 05:28:08 +08:00
										 |  |  | 		this.cachePredicate = typeof options.unsafeCache === "function" ? options.unsafeCache : Boolean.bind(null, options.unsafeCache); | 
					
						
							|  |  |  | 		this.context = context || ""; | 
					
						
							| 
									
										
										
										
											2018-01-22 05:35:30 +08:00
										 |  |  | 		this.parserCache = Object.create(null); | 
					
						
							| 
									
										
										
										
											2017-12-14 04:35:39 +08:00
										 |  |  | 		this.hooks.factory.tap("NormalModuleFactory", () => (result, callback) => { | 
					
						
							| 
									
										
										
										
											2017-11-28 16:54:24 +08:00
										 |  |  | 			let resolver = this.hooks.resolver.call(null); | 
					
						
							| 
									
										
										
										
											2015-05-13 06:15:01 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-24 17:54:58 +08:00
										 |  |  | 			// Ignored
 | 
					
						
							|  |  |  | 			if(!resolver) return callback(); | 
					
						
							| 
									
										
										
										
											2015-05-13 06:15:01 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-24 17:54:58 +08:00
										 |  |  | 			resolver(result, (err, data) => { | 
					
						
							|  |  |  | 				if(err) return callback(err); | 
					
						
							| 
									
										
										
										
											2015-05-13 06:15:01 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-24 17:54:58 +08:00
										 |  |  | 				// Ignored
 | 
					
						
							|  |  |  | 				if(!data) return callback(); | 
					
						
							| 
									
										
										
										
											2015-05-13 06:15:01 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-24 17:54:58 +08:00
										 |  |  | 				// direct module
 | 
					
						
							|  |  |  | 				if(typeof data.source === "function") | 
					
						
							|  |  |  | 					return callback(null, data); | 
					
						
							| 
									
										
										
										
											2016-02-10 02:32:50 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-28 16:54:24 +08:00
										 |  |  | 				this.hooks.afterResolve.callAsync(data, (err, result) => { | 
					
						
							| 
									
										
										
										
											2017-07-24 17:54:58 +08:00
										 |  |  | 					if(err) return callback(err); | 
					
						
							| 
									
										
										
										
											2015-05-17 00:27:59 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-24 17:54:58 +08:00
										 |  |  | 					// Ignored
 | 
					
						
							|  |  |  | 					if(!result) return callback(); | 
					
						
							| 
									
										
										
										
											2015-05-17 00:27:59 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-28 16:54:24 +08:00
										 |  |  | 					let createdModule = this.hooks.createModule.call(result); | 
					
						
							| 
									
										
										
										
											2017-07-24 17:54:58 +08:00
										 |  |  | 					if(!createdModule) { | 
					
						
							| 
									
										
										
										
											2017-02-21 00:09:20 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-24 17:54:58 +08:00
										 |  |  | 						if(!result.request) { | 
					
						
							|  |  |  | 							return callback(new Error("Empty dependency (no request)")); | 
					
						
							| 
									
										
										
										
											2016-11-23 00:58:24 +08:00
										 |  |  | 						} | 
					
						
							| 
									
										
										
										
											2017-04-04 05:28:08 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-24 17:54:58 +08:00
										 |  |  | 						createdModule = new NormalModule( | 
					
						
							| 
									
										
										
										
											2017-10-30 20:56:57 +08:00
										 |  |  | 							result.type, | 
					
						
							| 
									
										
										
										
											2017-07-24 17:54:58 +08:00
										 |  |  | 							result.request, | 
					
						
							|  |  |  | 							result.userRequest, | 
					
						
							|  |  |  | 							result.rawRequest, | 
					
						
							|  |  |  | 							result.loaders, | 
					
						
							|  |  |  | 							result.resource, | 
					
						
							| 
									
										
										
										
											2017-11-17 21:26:23 +08:00
										 |  |  | 							result.parser, | 
					
						
							|  |  |  | 							result.resolveOptions | 
					
						
							| 
									
										
										
										
											2017-04-04 05:28:08 +08:00
										 |  |  | 						); | 
					
						
							|  |  |  | 					} | 
					
						
							| 
									
										
										
										
											2015-05-13 06:15:01 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-28 16:54:24 +08:00
										 |  |  | 					createdModule = this.hooks.module.call(createdModule, result); | 
					
						
							| 
									
										
										
										
											2015-05-16 20:59:50 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-24 17:54:58 +08:00
										 |  |  | 					return callback(null, createdModule); | 
					
						
							|  |  |  | 				}); | 
					
						
							|  |  |  | 			}); | 
					
						
							|  |  |  | 		}); | 
					
						
							| 
									
										
										
										
											2017-12-14 04:35:39 +08:00
										 |  |  | 		this.hooks.resolver.tap("NormalModuleFactory", () => (data, callback) => { | 
					
						
							| 
									
										
										
										
											2017-07-24 17:54:58 +08:00
										 |  |  | 			const contextInfo = data.contextInfo; | 
					
						
							|  |  |  | 			const context = data.context; | 
					
						
							|  |  |  | 			const request = data.request; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-20 05:29:44 +08:00
										 |  |  | 			const noPreAutoLoaders = request.startsWith("-!"); | 
					
						
							|  |  |  | 			const noAutoLoaders = noPreAutoLoaders || request.startsWith("!"); | 
					
						
							|  |  |  | 			const noPrePostAutoLoaders = request.startsWith("!!"); | 
					
						
							| 
									
										
										
										
											2017-07-24 17:54:58 +08:00
										 |  |  | 			let elements = request.replace(/^-?!+/, "").replace(/!!+/g, "!").split("!"); | 
					
						
							|  |  |  | 			let resource = elements.pop(); | 
					
						
							|  |  |  | 			elements = elements.map(identToLoaderRequest); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-17 21:26:23 +08:00
										 |  |  | 			const loaderResolver = this.getResolver("loader"); | 
					
						
							|  |  |  | 			const normalResolver = this.getResolver("normal", data.resolveOptions); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-24 17:54:58 +08:00
										 |  |  | 			asyncLib.parallel([ | 
					
						
							| 
									
										
										
										
											2017-11-17 21:26:23 +08:00
										 |  |  | 				callback => this.resolveRequestArray(contextInfo, context, elements, loaderResolver, callback), | 
					
						
							| 
									
										
										
										
											2017-07-24 17:54:58 +08:00
										 |  |  | 				callback => { | 
					
						
							| 
									
										
										
										
											2017-11-17 21:26:23 +08:00
										 |  |  | 					if(resource === "" || resource[0] === "?") { | 
					
						
							| 
									
										
										
										
											2017-07-24 17:54:58 +08:00
										 |  |  | 						return callback(null, { | 
					
						
							|  |  |  | 							resource | 
					
						
							|  |  |  | 						}); | 
					
						
							| 
									
										
										
										
											2017-11-17 21:26:23 +08:00
										 |  |  | 					} | 
					
						
							| 
									
										
										
										
											2015-07-13 06:20:09 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-23 02:35:04 +08:00
										 |  |  | 					normalResolver.resolve(contextInfo, context, resource, {}, (err, resource, resourceResolveData) => { | 
					
						
							| 
									
										
										
										
											2017-07-24 17:54:58 +08:00
										 |  |  | 						if(err) return callback(err); | 
					
						
							|  |  |  | 						callback(null, { | 
					
						
							|  |  |  | 							resourceResolveData, | 
					
						
							|  |  |  | 							resource | 
					
						
							|  |  |  | 						}); | 
					
						
							| 
									
										
										
										
											2015-05-13 06:15:01 +08:00
										 |  |  | 					}); | 
					
						
							| 
									
										
										
										
											2017-07-24 17:54:58 +08:00
										 |  |  | 				} | 
					
						
							|  |  |  | 			], (err, results) => { | 
					
						
							|  |  |  | 				if(err) return callback(err); | 
					
						
							|  |  |  | 				let loaders = results[0]; | 
					
						
							|  |  |  | 				const resourceResolveData = results[1].resourceResolveData; | 
					
						
							|  |  |  | 				resource = results[1].resource; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				// translate option idents
 | 
					
						
							|  |  |  | 				try { | 
					
						
							|  |  |  | 					loaders.forEach(item => { | 
					
						
							| 
									
										
										
										
											2018-01-20 05:29:44 +08:00
										 |  |  | 						if(typeof item.options === "string" && item.options[0] === "?") { | 
					
						
							| 
									
										
										
										
											2017-12-22 01:14:16 +08:00
										 |  |  | 							const ident = item.options.substr(1); | 
					
						
							|  |  |  | 							item.options = this.ruleSet.findOptionsByIdent(ident); | 
					
						
							|  |  |  | 							item.ident = ident; | 
					
						
							| 
									
										
										
										
											2017-04-04 05:28:08 +08:00
										 |  |  | 						} | 
					
						
							|  |  |  | 					}); | 
					
						
							| 
									
										
										
										
											2017-07-24 17:54:58 +08:00
										 |  |  | 				} catch(e) { | 
					
						
							|  |  |  | 					return callback(e); | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				if(resource === false) { | 
					
						
							|  |  |  | 					// ignored
 | 
					
						
							|  |  |  | 					return callback(null, | 
					
						
							|  |  |  | 						new RawModule( | 
					
						
							|  |  |  | 							"/* (ignored) */", | 
					
						
							|  |  |  | 							`ignored ${context} ${request}`, | 
					
						
							|  |  |  | 							`${request} (ignored)` | 
					
						
							|  |  |  | 						) | 
					
						
							|  |  |  | 					); | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				const userRequest = loaders.map(loaderToIdent).concat([resource]).join("!"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				let resourcePath = resource; | 
					
						
							|  |  |  | 				let resourceQuery = ""; | 
					
						
							|  |  |  | 				const queryIndex = resourcePath.indexOf("?"); | 
					
						
							|  |  |  | 				if(queryIndex >= 0) { | 
					
						
							|  |  |  | 					resourceQuery = resourcePath.substr(queryIndex); | 
					
						
							|  |  |  | 					resourcePath = resourcePath.substr(0, queryIndex); | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				const result = this.ruleSet.exec({ | 
					
						
							|  |  |  | 					resource: resourcePath, | 
					
						
							|  |  |  | 					resourceQuery, | 
					
						
							|  |  |  | 					issuer: contextInfo.issuer, | 
					
						
							|  |  |  | 					compiler: contextInfo.compiler | 
					
						
							|  |  |  | 				}); | 
					
						
							|  |  |  | 				const settings = {}; | 
					
						
							|  |  |  | 				const useLoadersPost = []; | 
					
						
							|  |  |  | 				const useLoaders = []; | 
					
						
							|  |  |  | 				const useLoadersPre = []; | 
					
						
							|  |  |  | 				result.forEach(r => { | 
					
						
							|  |  |  | 					if(r.type === "use") { | 
					
						
							| 
									
										
										
										
											2017-12-31 02:34:14 +08:00
										 |  |  | 						if(r.enforce === "post" && !noPrePostAutoLoaders) | 
					
						
							| 
									
										
										
										
											2017-07-24 17:54:58 +08:00
										 |  |  | 							useLoadersPost.push(r.value); | 
					
						
							| 
									
										
										
										
											2017-12-31 02:34:14 +08:00
										 |  |  | 						else if(r.enforce === "pre" && !noPreAutoLoaders && !noPrePostAutoLoaders) | 
					
						
							| 
									
										
										
										
											2017-07-24 17:54:58 +08:00
										 |  |  | 							useLoadersPre.push(r.value); | 
					
						
							|  |  |  | 						else if(!r.enforce && !noAutoLoaders && !noPrePostAutoLoaders) | 
					
						
							|  |  |  | 							useLoaders.push(r.value); | 
					
						
							| 
									
										
										
										
											2017-11-17 21:26:23 +08:00
										 |  |  | 					} else if(typeof r.value === "object" && r.value !== null && typeof settings[r.type] === "object" && settings[r.type] !== null) { | 
					
						
							|  |  |  | 						settings[r.type] = cachedMerge(settings[r.type], r.value); | 
					
						
							| 
									
										
										
										
											2017-07-24 17:54:58 +08:00
										 |  |  | 					} else { | 
					
						
							|  |  |  | 						settings[r.type] = r.value; | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 				}); | 
					
						
							|  |  |  | 				asyncLib.parallel([ | 
					
						
							| 
									
										
										
										
											2017-11-17 21:26:23 +08:00
										 |  |  | 					this.resolveRequestArray.bind(this, contextInfo, this.context, useLoadersPost, loaderResolver), | 
					
						
							|  |  |  | 					this.resolveRequestArray.bind(this, contextInfo, this.context, useLoaders, loaderResolver), | 
					
						
							|  |  |  | 					this.resolveRequestArray.bind(this, contextInfo, this.context, useLoadersPre, loaderResolver) | 
					
						
							| 
									
										
										
										
											2017-07-24 17:54:58 +08:00
										 |  |  | 				], (err, results) => { | 
					
						
							|  |  |  | 					if(err) return callback(err); | 
					
						
							|  |  |  | 					loaders = results[0].concat(loaders, results[1], results[2]); | 
					
						
							|  |  |  | 					process.nextTick(() => { | 
					
						
							| 
									
										
										
										
											2017-11-17 21:26:23 +08:00
										 |  |  | 						const type = settings.type; | 
					
						
							|  |  |  | 						const resolveOptions = settings.resolve; | 
					
						
							| 
									
										
										
										
											2017-07-24 17:54:58 +08:00
										 |  |  | 						callback(null, { | 
					
						
							|  |  |  | 							context: context, | 
					
						
							|  |  |  | 							request: loaders.map(loaderToIdent).concat([resource]).join("!"), | 
					
						
							|  |  |  | 							dependencies: data.dependencies, | 
					
						
							|  |  |  | 							userRequest, | 
					
						
							|  |  |  | 							rawRequest: request, | 
					
						
							|  |  |  | 							loaders, | 
					
						
							|  |  |  | 							resource, | 
					
						
							|  |  |  | 							resourceResolveData, | 
					
						
							| 
									
										
										
										
											2017-12-06 19:09:34 +08:00
										 |  |  | 							settings, | 
					
						
							| 
									
										
										
										
											2017-10-30 20:56:57 +08:00
										 |  |  | 							type, | 
					
						
							| 
									
										
										
										
											2017-11-17 21:26:23 +08:00
										 |  |  | 							parser: this.getParser(type, settings.parser), | 
					
						
							|  |  |  | 							resolveOptions | 
					
						
							| 
									
										
										
										
											2017-04-04 05:28:08 +08:00
										 |  |  | 						}); | 
					
						
							|  |  |  | 					}); | 
					
						
							|  |  |  | 				}); | 
					
						
							| 
									
										
										
										
											2017-07-24 17:54:58 +08:00
										 |  |  | 			}); | 
					
						
							| 
									
										
										
										
											2017-04-04 05:28:08 +08:00
										 |  |  | 		}); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2013-01-31 01:49:25 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-04 05:28:08 +08:00
										 |  |  | 	create(data, callback) { | 
					
						
							| 
									
										
										
										
											2017-04-04 16:26:16 +08:00
										 |  |  | 		const dependencies = data.dependencies; | 
					
						
							|  |  |  | 		const cacheEntry = dependencies[0].__NormalModuleFactoryCache; | 
					
						
							| 
									
										
										
										
											2017-04-04 05:28:08 +08:00
										 |  |  | 		if(cacheEntry) return callback(null, cacheEntry); | 
					
						
							| 
									
										
										
										
											2017-04-04 16:26:16 +08:00
										 |  |  | 		const context = data.context || this.context; | 
					
						
							| 
									
										
										
										
											2017-11-17 21:26:23 +08:00
										 |  |  | 		const resolveOptions = data.resolveOptions || EMPTY_RESOLVE_OPTIONS; | 
					
						
							| 
									
										
										
										
											2017-04-04 16:26:16 +08:00
										 |  |  | 		const request = dependencies[0].request; | 
					
						
							|  |  |  | 		const contextInfo = data.contextInfo || {}; | 
					
						
							| 
									
										
										
										
											2017-11-28 16:54:24 +08:00
										 |  |  | 		this.hooks.beforeResolve.callAsync({ | 
					
						
							| 
									
										
										
										
											2017-04-04 05:28:08 +08:00
										 |  |  | 			contextInfo, | 
					
						
							| 
									
										
										
										
											2017-11-17 21:26:23 +08:00
										 |  |  | 			resolveOptions, | 
					
						
							| 
									
										
										
										
											2017-04-04 05:28:08 +08:00
										 |  |  | 			context, | 
					
						
							|  |  |  | 			request, | 
					
						
							|  |  |  | 			dependencies | 
					
						
							|  |  |  | 		}, (err, result) => { | 
					
						
							| 
									
										
										
										
											2016-12-05 06:47:19 +08:00
										 |  |  | 			if(err) return callback(err); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-04 05:28:08 +08:00
										 |  |  | 			// Ignored
 | 
					
						
							|  |  |  | 			if(!result) return callback(); | 
					
						
							| 
									
										
										
										
											2016-12-05 06:47:19 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-28 16:54:24 +08:00
										 |  |  | 			const factory = this.hooks.factory.call(null); | 
					
						
							| 
									
										
										
										
											2013-11-06 01:19:04 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-04 05:28:08 +08:00
										 |  |  | 			// Ignored
 | 
					
						
							|  |  |  | 			if(!factory) return callback(); | 
					
						
							| 
									
										
										
										
											2016-12-08 16:39:30 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-04 05:28:08 +08:00
										 |  |  | 			factory(result, (err, module) => { | 
					
						
							|  |  |  | 				if(err) return callback(err); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				if(module && this.cachePredicate(module)) { | 
					
						
							|  |  |  | 					dependencies.forEach(d => d.__NormalModuleFactoryCache = module); | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				callback(null, module); | 
					
						
							|  |  |  | 			}); | 
					
						
							| 
									
										
										
										
											2016-09-14 18:04:42 +08:00
										 |  |  | 		}); | 
					
						
							| 
									
										
										
										
											2016-09-14 18:04:42 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-04-04 05:28:08 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	resolveRequestArray(contextInfo, context, array, resolver, callback) { | 
					
						
							|  |  |  | 		if(array.length === 0) return callback(null, []); | 
					
						
							| 
									
										
										
										
											2017-04-05 21:06:23 +08:00
										 |  |  | 		asyncLib.map(array, (item, callback) => { | 
					
						
							| 
									
										
										
										
											2017-12-23 02:35:04 +08:00
										 |  |  | 			resolver.resolve(contextInfo, context, item.loader, {}, (err, result) => { | 
					
						
							| 
									
										
										
										
											2017-04-04 05:28:08 +08:00
										 |  |  | 				if(err && /^[^/]*$/.test(item.loader) && !/-loader$/.test(item.loader)) { | 
					
						
							| 
									
										
										
										
											2017-12-23 02:35:04 +08:00
										 |  |  | 					return resolver.resolve(contextInfo, context, item.loader + "-loader", {}, err2 => { | 
					
						
							| 
									
										
										
										
											2017-04-04 05:28:08 +08:00
										 |  |  | 						if(!err2) { | 
					
						
							|  |  |  | 							err.message = err.message + "\n" + | 
					
						
							|  |  |  | 								"BREAKING CHANGE: It's no longer allowed to omit the '-loader' suffix when using loaders.\n" + | 
					
						
							|  |  |  | 								`                 You need to specify '${item.loader}-loader' instead of '${item.loader}',\n` + | 
					
						
							|  |  |  | 								"                 see https://webpack.js.org/guides/migrating/#automatic-loader-module-name-extension-removed"; | 
					
						
							|  |  |  | 						} | 
					
						
							|  |  |  | 						callback(err); | 
					
						
							|  |  |  | 					}); | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				if(err) return callback(err); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-04 16:26:16 +08:00
										 |  |  | 				const optionsOnly = item.options ? { | 
					
						
							| 
									
										
										
										
											2017-04-04 05:28:08 +08:00
										 |  |  | 					options: item.options | 
					
						
							|  |  |  | 				} : undefined; | 
					
						
							|  |  |  | 				return callback(null, Object.assign({}, item, identToLoaderRequest(result), optionsOnly)); | 
					
						
							|  |  |  | 			}); | 
					
						
							|  |  |  | 		}, callback); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-10-30 20:56:57 +08:00
										 |  |  | 	getParser(type, parserOptions) { | 
					
						
							|  |  |  | 		let ident = type; | 
					
						
							| 
									
										
										
										
											2017-04-04 05:28:08 +08:00
										 |  |  | 		if(parserOptions) { | 
					
						
							|  |  |  | 			if(parserOptions.ident) | 
					
						
							| 
									
										
										
										
											2017-10-30 20:56:57 +08:00
										 |  |  | 				ident = `${type}|${parserOptions.ident}`; | 
					
						
							| 
									
										
										
										
											2017-04-04 05:28:08 +08:00
										 |  |  | 			else | 
					
						
							| 
									
										
										
										
											2017-10-30 20:56:57 +08:00
										 |  |  | 				ident = JSON.stringify([type, parserOptions]); | 
					
						
							| 
									
										
										
										
											2017-04-04 05:28:08 +08:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2018-01-22 05:35:30 +08:00
										 |  |  | 		if(ident in this.parserCache) { | 
					
						
							|  |  |  | 			return this.parserCache[ident]; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2017-10-30 20:56:57 +08:00
										 |  |  | 		return this.parserCache[ident] = this.createParser(type, parserOptions); | 
					
						
							| 
									
										
										
										
											2017-04-04 05:28:08 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-22 05:35:30 +08:00
										 |  |  | 	createParser(type, parserOptions = {}) { | 
					
						
							| 
									
										
										
										
											2017-11-28 16:54:24 +08:00
										 |  |  | 		const parser = this.hooks.createParser.for(type).call(parserOptions); | 
					
						
							| 
									
										
										
										
											2017-11-10 18:02:24 +08:00
										 |  |  | 		if(!parser) { | 
					
						
							|  |  |  | 			throw new Error(`No parser registered for ${type}`); | 
					
						
							| 
									
										
										
										
											2017-10-30 20:56:57 +08:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2017-11-28 16:54:24 +08:00
										 |  |  | 		this.hooks.parser.for(type).call(parser, parserOptions); | 
					
						
							| 
									
										
										
										
											2016-09-14 18:04:42 +08:00
										 |  |  | 		return parser; | 
					
						
							| 
									
										
										
										
											2017-04-04 05:28:08 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-11-17 21:26:23 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	getResolver(type, resolveOptions) { | 
					
						
							|  |  |  | 		return this.resolverFactory.get(type, resolveOptions || EMPTY_RESOLVE_OPTIONS); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-04-04 05:28:08 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | module.exports = NormalModuleFactory; |