| 
									
										
										
										
											2013-01-31 01:49:25 +08:00
										 |  |  | /* | 
					
						
							|  |  |  | 	MIT License http://www.opensource.org/licenses/mit-license.php
 | 
					
						
							|  |  |  | 	Author Tobias Koppers @sokra | 
					
						
							|  |  |  | */ | 
					
						
							|  |  |  | var async = require("async"); | 
					
						
							|  |  |  | var path = require("path"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | var Tapable = require("tapable"); | 
					
						
							|  |  |  | var ContextModule = require("./ContextModule"); | 
					
						
							|  |  |  | var ContextElementDependency = require("./dependencies/ContextElementDependency"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | function ContextModuleFactory(resolvers) { | 
					
						
							|  |  |  | 	Tapable.call(this); | 
					
						
							|  |  |  | 	this.resolvers = resolvers; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | module.exports = ContextModuleFactory; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ContextModuleFactory.prototype = Object.create(Tapable.prototype); | 
					
						
							| 
									
										
										
										
											2015-08-18 19:35:57 +08:00
										 |  |  | ContextModuleFactory.prototype.constructor = ContextModuleFactory; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-07-20 18:51:03 +08:00
										 |  |  | ContextModuleFactory.prototype.create = function(data, callback) { | 
					
						
							| 
									
										
										
										
											2016-01-02 07:21:54 +08:00
										 |  |  | 	var module = this; | 
					
						
							| 
									
										
										
										
											2016-07-20 18:51:03 +08:00
										 |  |  | 	var context = data.context; | 
					
						
							|  |  |  | 	var dependencies = data.dependencies; | 
					
						
							|  |  |  | 	var dependency = dependencies[0]; | 
					
						
							| 
									
										
										
										
											2013-01-31 01:49:25 +08:00
										 |  |  | 	this.applyPluginsAsyncWaterfall("before-resolve", { | 
					
						
							|  |  |  | 		context: context, | 
					
						
							|  |  |  | 		request: dependency.request, | 
					
						
							|  |  |  | 		recursive: dependency.recursive, | 
					
						
							| 
									
										
										
										
											2015-07-01 06:19:52 +08:00
										 |  |  | 		regExp: dependency.regExp, | 
					
						
							| 
									
										
										
										
											2016-07-20 18:51:03 +08:00
										 |  |  | 		async: dependency.async, | 
					
						
							|  |  |  | 		dependencies: dependencies | 
					
						
							| 
									
										
										
										
											2013-01-31 01:49:25 +08:00
										 |  |  | 	}, function(err, result) { | 
					
						
							|  |  |  | 		if(err) return callback(err); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-11-06 01:19:04 +08:00
										 |  |  | 		// Ignored
 | 
					
						
							|  |  |  | 		if(!result) return callback(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-01-31 01:49:25 +08:00
										 |  |  | 		var context = result.context; | 
					
						
							|  |  |  | 		var request = result.request; | 
					
						
							|  |  |  | 		var recursive = result.recursive; | 
					
						
							|  |  |  | 		var regExp = result.regExp; | 
					
						
							| 
									
										
										
										
											2015-07-01 06:19:52 +08:00
										 |  |  | 		var asyncContext = result.async; | 
					
						
							| 
									
										
										
										
											2016-07-20 18:51:03 +08:00
										 |  |  | 		var dependencies = result.dependencies; | 
					
						
							| 
									
										
										
										
											2013-01-31 01:49:25 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-02-04 19:34:20 +08:00
										 |  |  | 		var loaders, resource, loadersPrefix = ""; | 
					
						
							| 
									
										
										
										
											2013-01-31 01:49:25 +08:00
										 |  |  | 		var idx = request.lastIndexOf("!"); | 
					
						
							|  |  |  | 		if(idx >= 0) { | 
					
						
							| 
									
										
										
										
											2015-04-24 05:55:50 +08:00
										 |  |  | 			loaders = request.substr(0, idx + 1); | 
					
						
							| 
									
										
										
										
											2013-02-04 19:34:20 +08:00
										 |  |  | 			for(var i = 0; i < loaders.length && loaders[i] === "!"; i++) { | 
					
						
							|  |  |  | 				loadersPrefix += "!"; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			loaders = loaders.substr(i).replace(/!+$/, "").replace(/!!+/g, "!"); | 
					
						
							| 
									
										
										
										
											2014-06-25 00:53:32 +08:00
										 |  |  | 			if(loaders === "") loaders = []; | 
					
						
							| 
									
										
										
										
											2013-02-04 19:34:20 +08:00
										 |  |  | 			else loaders = loaders.split("!"); | 
					
						
							| 
									
										
										
										
											2015-04-24 05:55:50 +08:00
										 |  |  | 			resource = request.substr(idx + 1); | 
					
						
							| 
									
										
										
										
											2013-01-31 01:49:25 +08:00
										 |  |  | 		} else { | 
					
						
							| 
									
										
										
										
											2013-02-04 19:34:20 +08:00
										 |  |  | 			loaders = []; | 
					
						
							| 
									
										
										
										
											2013-01-31 01:49:25 +08:00
										 |  |  | 			resource = request; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-02 07:21:54 +08:00
										 |  |  | 		var resolvers = module.resolvers; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-02-04 19:34:20 +08:00
										 |  |  | 		async.parallel([ | 
					
						
							| 
									
										
										
										
											2016-01-02 07:21:54 +08:00
										 |  |  | 			function(callback) { | 
					
						
							|  |  |  | 				resolvers.context.resolve({}, context, resource, function(err, result) { | 
					
						
							|  |  |  | 					if(err) return callback(err); | 
					
						
							|  |  |  | 					callback(null, result); | 
					
						
							|  |  |  | 				}); | 
					
						
							|  |  |  | 			}, | 
					
						
							|  |  |  | 			function(callback) { | 
					
						
							|  |  |  | 				async.map(loaders, function(loader, callback) { | 
					
						
							|  |  |  | 					resolvers.loader.resolve({}, context, loader, function(err, result) { | 
					
						
							|  |  |  | 						if(err) return callback(err); | 
					
						
							|  |  |  | 						callback(null, result); | 
					
						
							| 
									
										
										
										
											2017-01-11 17:51:58 +08:00
										 |  |  | 					}); | 
					
						
							|  |  |  | 				}, callback); | 
					
						
							| 
									
										
										
										
											2016-01-02 07:21:54 +08:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2013-02-04 19:34:20 +08:00
										 |  |  | 		], function(err, result) { | 
					
						
							| 
									
										
										
										
											2013-01-31 01:49:25 +08:00
										 |  |  | 			if(err) return callback(err); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-02 07:21:54 +08:00
										 |  |  | 			module.applyPluginsAsyncWaterfall("after-resolve", { | 
					
						
							| 
									
										
										
										
											2013-02-04 19:34:20 +08:00
										 |  |  | 				loaders: loadersPrefix + result[1].join("!") + (result[1].length > 0 ? "!" : ""), | 
					
						
							|  |  |  | 				resource: result[0], | 
					
						
							| 
									
										
										
										
											2013-01-31 01:49:25 +08:00
										 |  |  | 				recursive: recursive, | 
					
						
							| 
									
										
										
										
											2015-07-01 06:19:52 +08:00
										 |  |  | 				regExp: regExp, | 
					
						
							| 
									
										
										
										
											2016-01-07 02:56:17 +08:00
										 |  |  | 				async: asyncContext, | 
					
						
							| 
									
										
										
										
											2016-07-20 18:51:03 +08:00
										 |  |  | 				dependencies: dependencies, | 
					
						
							| 
									
										
										
										
											2016-01-07 02:56:17 +08:00
										 |  |  | 				resolveDependencies: module.resolveDependencies.bind(module) | 
					
						
							| 
									
										
										
										
											2015-04-24 05:55:50 +08:00
										 |  |  | 			}, function(err, result) { | 
					
						
							| 
									
										
										
										
											2013-01-31 01:49:25 +08:00
										 |  |  | 				if(err) return callback(err); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-11-06 01:19:04 +08:00
										 |  |  | 				// Ignored
 | 
					
						
							|  |  |  | 				if(!result) return callback(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-07 02:56:17 +08:00
										 |  |  | 				return callback(null, new ContextModule(result.resolveDependencies, result.resource, result.recursive, result.regExp, result.loaders, result.async)); | 
					
						
							| 
									
										
										
										
											2016-01-02 07:21:54 +08:00
										 |  |  | 			}); | 
					
						
							|  |  |  | 		}); | 
					
						
							|  |  |  | 	}); | 
					
						
							| 
									
										
										
										
											2013-01-31 01:49:25 +08:00
										 |  |  | }; | 
					
						
							| 
									
										
										
										
											2013-02-04 19:34:20 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-01-31 01:49:25 +08:00
										 |  |  | ContextModuleFactory.prototype.resolveDependencies = function resolveDependencies(fs, resource, recursive, regExp, callback) { | 
					
						
							| 
									
										
										
										
											2015-03-06 05:57:52 +08:00
										 |  |  | 	if(!regExp || !resource) | 
					
						
							|  |  |  | 		return callback(null, []); | 
					
						
							| 
									
										
										
										
											2013-01-31 01:49:25 +08:00
										 |  |  | 	(function addDirectory(directory, callback) { | 
					
						
							|  |  |  | 		fs.readdir(directory, function(err, files) { | 
					
						
							| 
									
										
										
										
											2015-04-24 05:55:50 +08:00
										 |  |  | 			if(err) return callback(err); | 
					
						
							| 
									
										
										
										
											2014-11-02 19:16:55 +08:00
										 |  |  | 			if(!files || files.length === 0) return callback(null, []); | 
					
						
							| 
									
										
										
										
											2014-11-02 19:56:40 +08:00
										 |  |  | 			async.map(files.filter(function(p) { | 
					
						
							|  |  |  | 				return p.indexOf(".") !== 0; | 
					
						
							|  |  |  | 			}), function(seqment, callback) { | 
					
						
							| 
									
										
										
										
											2013-01-31 01:49:25 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-04-24 05:55:50 +08:00
										 |  |  | 				var subResource = path.join(directory, seqment); | 
					
						
							| 
									
										
										
										
											2013-01-31 01:49:25 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 				fs.stat(subResource, function(err, stat) { | 
					
						
							|  |  |  | 					if(err) return callback(err); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					if(stat.isDirectory()) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 						if(!recursive) return callback(); | 
					
						
							|  |  |  | 						addDirectory.call(this, subResource, callback); | 
					
						
							| 
									
										
										
										
											2013-02-04 19:34:20 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-01-31 01:49:25 +08:00
										 |  |  | 					} else if(stat.isFile()) { | 
					
						
							| 
									
										
										
										
											2013-02-04 19:34:20 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-01-31 01:49:25 +08:00
										 |  |  | 						var obj = { | 
					
						
							|  |  |  | 							context: resource, | 
					
						
							|  |  |  | 							request: "." + subResource.substr(resource.length).replace(/\\/g, "/") | 
					
						
							|  |  |  | 						}; | 
					
						
							| 
									
										
										
										
											2016-01-02 07:21:54 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-01-31 01:49:25 +08:00
										 |  |  | 						this.applyPluginsAsyncWaterfall("alternatives", [obj], function(err, alternatives) { | 
					
						
							| 
									
										
										
										
											2015-04-24 05:55:50 +08:00
										 |  |  | 							if(err) return callback(err); | 
					
						
							| 
									
										
										
										
											2013-01-31 01:49:25 +08:00
										 |  |  | 							alternatives = alternatives.filter(function(obj) { | 
					
						
							|  |  |  | 								return regExp.test(obj.request); | 
					
						
							|  |  |  | 							}).map(function(obj) { | 
					
						
							|  |  |  | 								var dep = new ContextElementDependency(obj.request); | 
					
						
							|  |  |  | 								dep.optional = true; | 
					
						
							|  |  |  | 								return dep; | 
					
						
							|  |  |  | 							}); | 
					
						
							|  |  |  | 							callback(null, alternatives); | 
					
						
							|  |  |  | 						}); | 
					
						
							| 
									
										
										
										
											2013-02-04 19:34:20 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-01-31 01:49:25 +08:00
										 |  |  | 					} else callback(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				}.bind(this)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			}.bind(this), function(err, result) { | 
					
						
							|  |  |  | 				if(err) return callback(err); | 
					
						
							| 
									
										
										
										
											2013-02-04 19:34:20 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-23 00:08:05 +08:00
										 |  |  | 				if(!result) return callback(null, []); | 
					
						
							| 
									
										
										
										
											2013-02-04 19:34:20 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-07-13 06:20:09 +08:00
										 |  |  | 				callback(null, result.filter(function(i) { | 
					
						
							|  |  |  | 					return !!i; | 
					
						
							|  |  |  | 				}).reduce(function(a, i) { | 
					
						
							| 
									
										
										
										
											2013-01-31 01:49:25 +08:00
										 |  |  | 					return a.concat(i); | 
					
						
							|  |  |  | 				}, [])); | 
					
						
							|  |  |  | 			}); | 
					
						
							|  |  |  | 		}.bind(this)); | 
					
						
							|  |  |  | 	}.call(this, resource, callback)); | 
					
						
							|  |  |  | }; |