| 
									
										
										
										
											2017-11-17 21:26:23 +08:00
										 |  |  | /* | 
					
						
							|  |  |  |  MIT License http://www.opensource.org/licenses/mit-license.php
 | 
					
						
							|  |  |  |  Author Tobias Koppers @sokra | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | "use strict"; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-28 23:45:27 +08:00
										 |  |  | const Tapable = require("tapable").Tapable; | 
					
						
							|  |  |  | const HookMap = require("tapable").HookMap; | 
					
						
							|  |  |  | const SyncHook = require("tapable").SyncHook; | 
					
						
							|  |  |  | const SyncWaterfallHook = require("tapable").SyncWaterfallHook; | 
					
						
							| 
									
										
										
										
											2017-11-17 21:26:23 +08:00
										 |  |  | const Factory = require("enhanced-resolve").ResolverFactory; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | module.exports = class ResolverFactory extends Tapable { | 
					
						
							|  |  |  | 	constructor() { | 
					
						
							|  |  |  | 		super(); | 
					
						
							| 
									
										
										
										
											2017-11-28 23:45:27 +08:00
										 |  |  | 		this.hooks = { | 
					
						
							|  |  |  | 			resolveOptions: new HookMap(() => new SyncWaterfallHook(["resolveOptions"])), | 
					
						
							|  |  |  | 			resolver: new HookMap(() => new SyncHook(["resolver", "resolveOptions"])), | 
					
						
							|  |  |  | 		}; | 
					
						
							|  |  |  | 		this._pluginCompat.tap("ResolverFactory", options => { | 
					
						
							|  |  |  | 			let match; | 
					
						
							|  |  |  | 			match = /^resolve-options (.+)$/.exec(options.name); | 
					
						
							|  |  |  | 			if(match) { | 
					
						
							|  |  |  | 				this.hooks.resolveOptions.tap(match[1], options.fn.name || "unnamed compat plugin", options.fn); | 
					
						
							|  |  |  | 				return true; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			match = /^resolver (.+)$/.exec(options.name); | 
					
						
							|  |  |  | 			if(match) { | 
					
						
							|  |  |  | 				this.hooks.resolver.tap(match[1], options.fn.name || "unnamed compat plugin", options.fn); | 
					
						
							|  |  |  | 				return true; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		}); | 
					
						
							| 
									
										
										
										
											2017-11-17 21:26:23 +08:00
										 |  |  | 		this.cache1 = new WeakMap(); | 
					
						
							|  |  |  | 		this.cache2 = new Map(); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	get(type, resolveOptions) { | 
					
						
							|  |  |  | 		const cachedResolver = this.cache1.get(resolveOptions); | 
					
						
							|  |  |  | 		if(cachedResolver) return cachedResolver(); | 
					
						
							|  |  |  | 		const ident = `${type}|${JSON.stringify(resolveOptions)}`; | 
					
						
							|  |  |  | 		const resolver = this.cache2.get(ident); | 
					
						
							|  |  |  | 		if(resolver) return resolver; | 
					
						
							|  |  |  | 		const newResolver = this._create(type, resolveOptions); | 
					
						
							|  |  |  | 		this.cache2.set(ident, newResolver); | 
					
						
							|  |  |  | 		return newResolver; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	_create(type, resolveOptions) { | 
					
						
							| 
									
										
										
										
											2017-11-28 23:45:27 +08:00
										 |  |  | 		resolveOptions = this.hooks.resolveOptions.for(type).call(resolveOptions); | 
					
						
							| 
									
										
										
										
											2017-11-17 21:26:23 +08:00
										 |  |  | 		const resolver = Factory.createResolver(resolveOptions); | 
					
						
							|  |  |  | 		if(!resolver) { | 
					
						
							|  |  |  | 			throw new Error("No resolver created"); | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2017-11-28 23:45:27 +08:00
										 |  |  | 		this.hooks.resolver.for(type).call(resolver, resolveOptions); | 
					
						
							| 
									
										
										
										
											2017-11-17 21:26:23 +08:00
										 |  |  | 		return resolver; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | }; |