228 lines
		
	
	
		
			6.1 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			228 lines
		
	
	
		
			6.1 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| /*
 | |
| 	MIT License http://www.opensource.org/licenses/mit-license.php
 | |
| 	Author Tobias Koppers @sokra
 | |
| */
 | |
| var Tapable = require("tapable");
 | |
| var createInnerCallback = require("./createInnerCallback");
 | |
| 
 | |
| function Resolver(fileSystem) {
 | |
| 	Tapable.call(this);
 | |
| 	this.fileSystem = fileSystem;
 | |
| }
 | |
| module.exports = Resolver;
 | |
| 
 | |
| Resolver.prototype = Object.create(Tapable.prototype);
 | |
| 
 | |
| Resolver.prototype.constructor = Resolver;
 | |
| 
 | |
| Resolver.prototype.resolveSync = function resolveSync(context, path, request) {
 | |
| 	var err, result, sync = false;
 | |
| 	this.resolve(context, path, request, function(e, r) {
 | |
| 		err = e;
 | |
| 		result = r;
 | |
| 		sync = true;
 | |
| 	});
 | |
| 	if(!sync) throw new Error("Cannot 'resolveSync' because the fileSystem is not sync. Use 'resolve'!");
 | |
| 	if(err) throw err;
 | |
| 	return result;
 | |
| };
 | |
| 
 | |
| Resolver.prototype.resolve = function resolve(context, path, request, callback) {
 | |
| 	if(arguments.length === 3) {
 | |
| 		throw new Error("Signature changed: context parameter added");
 | |
| 	}
 | |
| 	var resolver = this;
 | |
| 	var obj = {
 | |
| 		context: context,
 | |
| 		path: path,
 | |
| 		request: request
 | |
| 	};
 | |
| 
 | |
| 	var localMissing;
 | |
| 	var log;
 | |
| 	var message = "resolve '" + request + "' in '" + path + "'";
 | |
| 
 | |
| 	function writeLog(msg) {
 | |
| 		log.push(msg);
 | |
| 	}
 | |
| 
 | |
| 	function logAsString() {
 | |
| 		return log.join("\n");
 | |
| 	}
 | |
| 
 | |
| 	function onError(err, result) {
 | |
| 		if(callback.log) {
 | |
| 			for(var i = 0; i < log.length; i++)
 | |
| 				callback.log(log[i]);
 | |
| 		}
 | |
| 
 | |
| 		if(err) return callback(err);
 | |
| 
 | |
| 		var error = new Error("Can't " + message);
 | |
| 		error.details = logAsString();
 | |
| 		error.missing = localMissing;
 | |
| 		resolver.applyPlugins("no-resolve", obj, error);
 | |
| 		return callback(error);
 | |
| 	}
 | |
| 
 | |
| 	function onResolve(err, result) {
 | |
| 		if(!err && result) {
 | |
| 			return callback(null, result.path === false ? false : result.path + (result.query || ""), result);
 | |
| 		}
 | |
| 
 | |
| 		localMissing = [];
 | |
| 		log = [];
 | |
| 
 | |
| 		return resolver.doResolve("resolve", obj, message, createInnerCallback(onError, {
 | |
| 			log: writeLog,
 | |
| 			missing: localMissing,
 | |
| 			stack: callback.stack
 | |
| 		}));
 | |
| 	}
 | |
| 
 | |
| 	onResolve.missing = callback.missing;
 | |
| 	onResolve.stack = callback.stack;
 | |
| 
 | |
| 	return this.doResolve("resolve", obj, message, onResolve);
 | |
| };
 | |
| 
 | |
| Resolver.prototype.doResolve = function doResolve(type, request, message, callback) {
 | |
| 	var resolver = this;
 | |
| 	var stackLine = type + ": (" + request.path + ") " +
 | |
| 		(request.request || "") + (request.query || "") +
 | |
| 		(request.directory ? " directory" : "") +
 | |
| 		(request.module ? " module" : "");
 | |
| 	var newStack = [stackLine];
 | |
| 	if(callback.stack) {
 | |
| 		newStack = callback.stack.concat(newStack);
 | |
| 		if(callback.stack.indexOf(stackLine) >= 0) {
 | |
| 			// Prevent recursion
 | |
| 			var recursionError = new Error("Recursion in resolving\nStack:\n  " + newStack.join("\n  "));
 | |
| 			recursionError.recursion = true;
 | |
| 			if(callback.log) callback.log("abort resolving because of recursion");
 | |
| 			return callback(recursionError);
 | |
| 		}
 | |
| 	}
 | |
| 	resolver.applyPlugins("resolve-step", type, request);
 | |
| 
 | |
| 	var beforePluginName = "before-" + type;
 | |
| 	if(resolver.hasPlugins(beforePluginName)) {
 | |
| 		resolver.applyPluginsAsyncSeriesBailResult1(beforePluginName, request, createInnerCallback(beforeInnerCallback, {
 | |
| 			log: callback.log,
 | |
| 			missing: callback.missing,
 | |
| 			stack: newStack
 | |
| 		}, message && ("before " + message), true));
 | |
| 	} else {
 | |
| 		runNormal();
 | |
| 	}
 | |
| 
 | |
| 	function beforeInnerCallback(err, result) {
 | |
| 		if(arguments.length > 0) {
 | |
| 			if(err) return callback(err);
 | |
| 			if(result) return callback(null, result);
 | |
| 			return callback();
 | |
| 		}
 | |
| 		runNormal();
 | |
| 	}
 | |
| 
 | |
| 	function runNormal() {
 | |
| 		if(resolver.hasPlugins(type)) {
 | |
| 			return resolver.applyPluginsAsyncSeriesBailResult1(type, request, createInnerCallback(innerCallback, {
 | |
| 				log: callback.log,
 | |
| 				missing: callback.missing,
 | |
| 				stack: newStack
 | |
| 			}, message));
 | |
| 		} else {
 | |
| 			runAfter();
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	function innerCallback(err, result) {
 | |
| 		if(arguments.length > 0) {
 | |
| 			if(err) return callback(err);
 | |
| 			if(result) return callback(null, result);
 | |
| 			return callback();
 | |
| 		}
 | |
| 		runAfter();
 | |
| 	}
 | |
| 
 | |
| 	function runAfter() {
 | |
| 		var afterPluginName = "after-" + type;
 | |
| 		if(resolver.hasPlugins(afterPluginName)) {
 | |
| 			return resolver.applyPluginsAsyncSeriesBailResult1(afterPluginName, request, createInnerCallback(afterInnerCallback, {
 | |
| 				log: callback.log,
 | |
| 				missing: callback.missing,
 | |
| 				stack: newStack
 | |
| 			}, message && ("after " + message), true));
 | |
| 		} else {
 | |
| 			callback();
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	function afterInnerCallback(err, result) {
 | |
| 		if(arguments.length > 0) {
 | |
| 			if(err) return callback(err);
 | |
| 			if(result) return callback(null, result);
 | |
| 			return callback();
 | |
| 		}
 | |
| 		return callback();
 | |
| 	}
 | |
| };
 | |
| 
 | |
| Resolver.prototype.parse = function parse(identifier) {
 | |
| 	if(identifier === "") return null;
 | |
| 	var part = {
 | |
| 		request: "",
 | |
| 		query: "",
 | |
| 		module: false,
 | |
| 		directory: false,
 | |
| 		file: false
 | |
| 	};
 | |
| 	var idxQuery = identifier.indexOf("?");
 | |
| 	if(idxQuery === 0) {
 | |
| 		part.query = identifier;
 | |
| 	} else if(idxQuery > 0) {
 | |
| 		part.request = identifier.slice(0, idxQuery);
 | |
| 		part.query = identifier.slice(idxQuery);
 | |
| 	} else {
 | |
| 		part.request = identifier;
 | |
| 	}
 | |
| 	if(part.request) {
 | |
| 		part.module = this.isModule(part.request);
 | |
| 		part.directory = this.isDirectory(part.request);
 | |
| 		if(part.directory) {
 | |
| 			part.request = part.request.substr(0, part.request.length - 1);
 | |
| 		}
 | |
| 	}
 | |
| 	return part;
 | |
| };
 | |
| 
 | |
| var notModuleRegExp = /^\.$|^\.[\\\/]|^\.\.$|^\.\.[\/\\]|^\/|^[A-Z]:[\\\/]/i;
 | |
| Resolver.prototype.isModule = function isModule(path) {
 | |
| 	return !notModuleRegExp.test(path);
 | |
| };
 | |
| 
 | |
| var directoryRegExp = /[\/\\]$/i;
 | |
| Resolver.prototype.isDirectory = function isDirectory(path) {
 | |
| 	return directoryRegExp.test(path);
 | |
| };
 | |
| 
 | |
| var memoryFsJoin = require("memory-fs/lib/join");
 | |
| var memoizedJoin = new Map();
 | |
| Resolver.prototype.join = function(path, request) {
 | |
| 	var cacheEntry;
 | |
| 	var pathCache = memoizedJoin.get(path);
 | |
| 	if(typeof pathCache === "undefined") {
 | |
| 		memoizedJoin.set(path, pathCache = new Map());
 | |
| 	} else {
 | |
| 		cacheEntry = pathCache.get(request);
 | |
| 		if(typeof cacheEntry !== "undefined")
 | |
| 			return cacheEntry;
 | |
| 	}
 | |
| 	cacheEntry = memoryFsJoin(path, request);
 | |
| 	pathCache.set(request, cacheEntry);
 | |
| 	return cacheEntry;
 | |
| };
 | |
| 
 | |
| Resolver.prototype.normalize = require("memory-fs/lib/normalize");
 |