| 
									
										
										
										
											2013-01-31 01:49:25 +08:00
										 |  |  | /* | 
					
						
							|  |  |  | 	MIT License http://www.opensource.org/licenses/mit-license.php
 | 
					
						
							|  |  |  | 	Author Tobias Koppers @sokra | 
					
						
							|  |  |  | */ | 
					
						
							| 
									
										
										
										
											2015-01-05 21:30:18 +08:00
										 |  |  | var path = require("path"); | 
					
						
							| 
									
										
										
										
											2016-04-22 03:41:37 +08:00
										 |  |  | var assign = require("object-assign"); | 
					
						
							| 
									
										
										
										
											2013-01-31 01:49:25 +08:00
										 |  |  | var Tapable = require("tapable"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | var Compilation = require("./Compilation"); | 
					
						
							|  |  |  | var Parser = require("./Parser"); | 
					
						
							|  |  |  | var Resolver = require("enhanced-resolve/lib/Resolver"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | var NormalModuleFactory = require("./NormalModuleFactory"); | 
					
						
							|  |  |  | var ContextModuleFactory = require("./ContextModuleFactory"); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-05-10 19:50:15 +08:00
										 |  |  | function Watching(compiler, watchOptions, handler) { | 
					
						
							| 
									
										
										
										
											2013-01-31 01:49:25 +08:00
										 |  |  | 	this.startTime = null; | 
					
						
							|  |  |  | 	this.invalid = false; | 
					
						
							|  |  |  | 	this.error = null; | 
					
						
							|  |  |  | 	this.stats = null; | 
					
						
							|  |  |  | 	this.handler = handler; | 
					
						
							| 
									
										
										
										
											2015-05-10 19:50:15 +08:00
										 |  |  | 	if(typeof watchOptions === "number") { | 
					
						
							|  |  |  | 		this.watchOptions = { | 
					
						
							|  |  |  | 			aggregateTimeout: watchOptions | 
					
						
							|  |  |  | 		}; | 
					
						
							|  |  |  | 	} else if(watchOptions && typeof watchOptions === "object") { | 
					
						
							| 
									
										
										
										
											2016-04-22 03:41:37 +08:00
										 |  |  | 		this.watchOptions = assign({}, watchOptions); | 
					
						
							| 
									
										
										
										
											2015-05-10 19:50:15 +08:00
										 |  |  | 	} else { | 
					
						
							|  |  |  | 		this.watchOptions = {}; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	this.watchOptions.aggregateTimeout = this.watchOptions.aggregateTimeout || 200; | 
					
						
							| 
									
										
										
										
											2013-01-31 01:49:25 +08:00
										 |  |  | 	this.compiler = compiler; | 
					
						
							| 
									
										
										
										
											2013-05-31 18:22:40 +08:00
										 |  |  | 	this.running = true; | 
					
						
							|  |  |  | 	this.compiler.readRecords(function(err) { | 
					
						
							|  |  |  | 		if(err) return this._done(err); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		this._go(); | 
					
						
							|  |  |  | 	}.bind(this)); | 
					
						
							| 
									
										
										
										
											2013-01-31 01:49:25 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Watching.prototype._go = function() { | 
					
						
							|  |  |  | 	this.startTime = new Date().getTime(); | 
					
						
							|  |  |  | 	this.running = true; | 
					
						
							|  |  |  | 	this.invalid = false; | 
					
						
							|  |  |  | 	this.compiler.applyPluginsAsync("watch-run", this, function(err) { | 
					
						
							| 
									
										
										
										
											2015-04-24 05:55:50 +08:00
										 |  |  | 		if(err) return this._done(err); | 
					
						
							| 
									
										
										
										
											2015-01-30 07:46:52 +08:00
										 |  |  | 		this.compiler.compile(function onCompiled(err, compilation) { | 
					
						
							| 
									
										
										
										
											2013-01-31 01:49:25 +08:00
										 |  |  | 			if(err) return this._done(err); | 
					
						
							|  |  |  | 			if(this.invalid) return this._done(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-09-03 20:16:17 +08:00
										 |  |  | 			if(this.compiler.applyPluginsBailResult("should-emit", compilation) === false) { | 
					
						
							|  |  |  | 				return this._done(null, compilation); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-01-31 01:49:25 +08:00
										 |  |  | 			this.compiler.emitAssets(compilation, function(err) { | 
					
						
							|  |  |  | 				if(err) return this._done(err); | 
					
						
							| 
									
										
										
										
											2013-05-31 18:22:40 +08:00
										 |  |  | 				if(this.invalid) return this._done(); | 
					
						
							| 
									
										
										
										
											2013-01-31 01:49:25 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-05-31 18:22:40 +08:00
										 |  |  | 				this.compiler.emitRecords(function(err) { | 
					
						
							|  |  |  | 					if(err) return this._done(err); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-30 07:46:52 +08:00
										 |  |  | 					if(compilation.applyPluginsBailResult("need-additional-pass")) { | 
					
						
							|  |  |  | 						compilation.needAdditionalPass = true; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 						var stats = compilation.getStats(); | 
					
						
							|  |  |  | 						stats.startTime = this.startTime; | 
					
						
							|  |  |  | 						stats.endTime = new Date().getTime(); | 
					
						
							|  |  |  | 						this.compiler.applyPlugins("done", stats); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 						this.compiler.applyPluginsAsync("additional-pass", function(err) { | 
					
						
							|  |  |  | 							if(err) return this._done(err); | 
					
						
							|  |  |  | 							this.compiler.compile(onCompiled.bind(this)); | 
					
						
							|  |  |  | 						}.bind(this)); | 
					
						
							|  |  |  | 						return; | 
					
						
							|  |  |  | 					} | 
					
						
							| 
									
										
										
										
											2013-05-31 18:22:40 +08:00
										 |  |  | 					return this._done(null, compilation); | 
					
						
							|  |  |  | 				}.bind(this)); | 
					
						
							| 
									
										
										
										
											2013-01-31 01:49:25 +08:00
										 |  |  | 			}.bind(this)); | 
					
						
							|  |  |  | 		}.bind(this)); | 
					
						
							|  |  |  | 	}.bind(this)); | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Watching.prototype._done = function(err, compilation) { | 
					
						
							|  |  |  | 	this.running = false; | 
					
						
							|  |  |  | 	if(this.invalid) return this._go(); | 
					
						
							|  |  |  | 	this.error = err || null; | 
					
						
							|  |  |  | 	this.stats = compilation ? compilation.getStats() : null; | 
					
						
							|  |  |  | 	if(this.stats) { | 
					
						
							|  |  |  | 		this.stats.startTime = this.startTime; | 
					
						
							|  |  |  | 		this.stats.endTime = new Date().getTime(); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if(this.stats) | 
					
						
							|  |  |  | 		this.compiler.applyPlugins("done", this.stats); | 
					
						
							|  |  |  | 	else | 
					
						
							|  |  |  | 		this.compiler.applyPlugins("failed", this.error); | 
					
						
							|  |  |  | 	this.handler(this.error, this.stats); | 
					
						
							|  |  |  | 	if(!this.error) | 
					
						
							| 
									
										
										
										
											2015-01-18 04:55:44 +08:00
										 |  |  | 		this.watch(compilation.fileDependencies, compilation.contextDependencies, compilation.missingDependencies); | 
					
						
							| 
									
										
										
										
											2013-01-31 01:49:25 +08:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-18 04:55:44 +08:00
										 |  |  | Watching.prototype.watch = function(files, dirs, missing) { | 
					
						
							| 
									
										
										
										
											2015-05-10 19:50:15 +08:00
										 |  |  | 	this.watcher = this.compiler.watchFileSystem.watch(files, dirs, missing, this.startTime, this.watchOptions, function(err, filesModified, contextModified, missingModified, fileTimestamps, contextTimestamps) { | 
					
						
							| 
									
										
										
										
											2013-01-31 01:49:25 +08:00
										 |  |  | 		this.watcher = null; | 
					
						
							|  |  |  | 		if(err) return this.handler(err); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		this.compiler.fileTimestamps = fileTimestamps; | 
					
						
							|  |  |  | 		this.compiler.contextTimestamps = contextTimestamps; | 
					
						
							|  |  |  | 		this.invalidate(); | 
					
						
							| 
									
										
										
										
											2016-03-20 18:53:55 +08:00
										 |  |  | 	}.bind(this), function(fileName, changeTime) { | 
					
						
							|  |  |  | 		this.compiler.applyPlugins("invalid", fileName, changeTime); | 
					
						
							| 
									
										
										
										
											2013-01-31 01:49:25 +08:00
										 |  |  | 	}.bind(this)); | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Watching.prototype.invalidate = function() { | 
					
						
							| 
									
										
										
										
											2014-05-08 15:08:01 +08:00
										 |  |  | 	if(this.watcher) { | 
					
						
							| 
									
										
										
										
											2015-01-18 04:55:44 +08:00
										 |  |  | 		this.watcher.pause(); | 
					
						
							| 
									
										
										
										
											2014-05-08 15:08:01 +08:00
										 |  |  | 		this.watcher = null; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2013-01-31 01:49:25 +08:00
										 |  |  | 	if(this.running) { | 
					
						
							|  |  |  | 		this.invalid = true; | 
					
						
							|  |  |  | 		return false; | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 		this._go(); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-08 15:08:01 +08:00
										 |  |  | Watching.prototype.close = function(callback) { | 
					
						
							| 
									
										
										
										
											2015-07-16 06:19:23 +08:00
										 |  |  | 	if(callback === undefined) callback = function() {}; | 
					
						
							| 
									
										
										
										
											2015-04-24 05:55:50 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-08 15:08:01 +08:00
										 |  |  | 	if(this.watcher) { | 
					
						
							|  |  |  | 		this.watcher.close(); | 
					
						
							|  |  |  | 		this.watcher = null; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if(this.running) { | 
					
						
							|  |  |  | 		this.invalid = true; | 
					
						
							|  |  |  | 		this._done = function() { | 
					
						
							|  |  |  | 			callback(); | 
					
						
							|  |  |  | 		}; | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 		callback(); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-01-31 01:49:25 +08:00
										 |  |  | function Compiler() { | 
					
						
							|  |  |  | 	Tapable.call(this); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	this.outputPath = ""; | 
					
						
							|  |  |  | 	this.outputFileSystem = null; | 
					
						
							|  |  |  | 	this.inputFileSystem = null; | 
					
						
							| 
									
										
										
										
											2013-05-08 19:28:54 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-05-31 18:22:40 +08:00
										 |  |  | 	this.recordsInputPath = null; | 
					
						
							|  |  |  | 	this.recordsOutputPath = null; | 
					
						
							|  |  |  | 	this.records = {}; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-01-31 01:49:25 +08:00
										 |  |  | 	this.fileTimestamps = {}; | 
					
						
							|  |  |  | 	this.contextTimestamps = {}; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	this.resolvers = { | 
					
						
							|  |  |  | 		normal: new Resolver(null), | 
					
						
							|  |  |  | 		loader: new Resolver(null), | 
					
						
							|  |  |  | 		context: new Resolver(null) | 
					
						
							|  |  |  | 	}; | 
					
						
							|  |  |  | 	this.parser = new Parser(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	this.options = {}; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | module.exports = Compiler; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Compiler.prototype = Object.create(Tapable.prototype); | 
					
						
							| 
									
										
										
										
											2015-08-18 19:35:57 +08:00
										 |  |  | Compiler.prototype.constructor = Compiler; | 
					
						
							| 
									
										
										
										
											2013-01-31 01:49:25 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | Compiler.Watching = Watching; | 
					
						
							| 
									
										
										
										
											2015-05-10 19:50:15 +08:00
										 |  |  | Compiler.prototype.watch = function(watchOptions, handler) { | 
					
						
							| 
									
										
										
										
											2013-01-31 01:49:25 +08:00
										 |  |  | 	this.fileTimestamps = {}; | 
					
						
							|  |  |  | 	this.contextTimestamps = {}; | 
					
						
							| 
									
										
										
										
											2015-05-10 19:50:15 +08:00
										 |  |  | 	var watching = new Watching(this, watchOptions, handler); | 
					
						
							| 
									
										
										
										
											2013-01-31 01:49:25 +08:00
										 |  |  | 	return watching; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Compiler.prototype.run = function(callback) { | 
					
						
							|  |  |  | 	var startTime = new Date().getTime(); | 
					
						
							| 
									
										
										
										
											2016-05-07 04:45:44 +08:00
										 |  |  | 	this.applyPluginsAsync("before-run", this, function(err) { | 
					
						
							| 
									
										
										
										
											2013-01-31 01:49:25 +08:00
										 |  |  | 		if(err) return callback(err); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-07 04:45:44 +08:00
										 |  |  | 		this.applyPluginsAsync("run", this, function(err) { | 
					
						
							| 
									
										
										
										
											2013-01-31 01:49:25 +08:00
										 |  |  | 			if(err) return callback(err); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-07 04:45:44 +08:00
										 |  |  | 			this.readRecords(function(err) { | 
					
						
							| 
									
										
										
										
											2013-01-31 01:49:25 +08:00
										 |  |  | 				if(err) return callback(err); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-07 04:45:44 +08:00
										 |  |  | 				this.compile(function onCompiled(err, compilation) { | 
					
						
							| 
									
										
										
										
											2013-05-31 18:22:40 +08:00
										 |  |  | 					if(err) return callback(err); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-07 04:45:44 +08:00
										 |  |  | 					if(this.applyPluginsBailResult("should-emit", compilation) === false) { | 
					
						
							| 
									
										
										
										
											2015-01-30 07:46:52 +08:00
										 |  |  | 						var stats = compilation.getStats(); | 
					
						
							|  |  |  | 						stats.startTime = startTime; | 
					
						
							|  |  |  | 						stats.endTime = new Date().getTime(); | 
					
						
							|  |  |  | 						this.applyPlugins("done", stats); | 
					
						
							| 
									
										
										
										
											2016-05-07 04:45:44 +08:00
										 |  |  | 						return callback(null, stats); | 
					
						
							| 
									
										
										
										
											2015-01-30 07:46:52 +08:00
										 |  |  | 					} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-07 04:45:44 +08:00
										 |  |  | 					this.emitAssets(compilation, function(err) { | 
					
						
							| 
									
										
										
										
											2013-05-31 18:22:40 +08:00
										 |  |  | 						if(err) return callback(err); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-07 04:45:44 +08:00
										 |  |  | 						if(compilation.applyPluginsBailResult("need-additional-pass")) { | 
					
						
							|  |  |  | 							compilation.needAdditionalPass = true; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 							var stats = compilation.getStats(); | 
					
						
							|  |  |  | 							stats.startTime = startTime; | 
					
						
							|  |  |  | 							stats.endTime = new Date().getTime(); | 
					
						
							|  |  |  | 							this.applyPlugins("done", stats); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 							this.applyPluginsAsync("additional-pass", function(err) { | 
					
						
							|  |  |  | 								if(err) return callback(err); | 
					
						
							|  |  |  | 								this.compile(onCompiled.bind(this)); | 
					
						
							|  |  |  | 							}.bind(this)); | 
					
						
							|  |  |  | 							return; | 
					
						
							|  |  |  | 						} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 						this.emitRecords(function(err) { | 
					
						
							|  |  |  | 							if(err) return callback(err); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 							var stats = compilation.getStats(); | 
					
						
							|  |  |  | 							stats.startTime = startTime; | 
					
						
							|  |  |  | 							stats.endTime = new Date().getTime(); | 
					
						
							|  |  |  | 							this.applyPlugins("done", stats); | 
					
						
							|  |  |  | 							return callback(null, stats); | 
					
						
							|  |  |  | 						}.bind(this)); | 
					
						
							| 
									
										
										
										
											2013-05-31 18:22:40 +08:00
										 |  |  | 					}.bind(this)); | 
					
						
							|  |  |  | 				}.bind(this)); | 
					
						
							| 
									
										
										
										
											2013-01-31 01:49:25 +08:00
										 |  |  | 			}.bind(this)); | 
					
						
							|  |  |  | 		}.bind(this)); | 
					
						
							|  |  |  | 	}.bind(this)); | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Compiler.prototype.runAsChild = function(callback) { | 
					
						
							|  |  |  | 	this.compile(function(err, compilation) { | 
					
						
							|  |  |  | 		if(err) return callback(err); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		this.parentCompilation.children.push(compilation); | 
					
						
							|  |  |  | 		Object.keys(compilation.assets).forEach(function(name) { | 
					
						
							|  |  |  | 			this.parentCompilation.assets[name] = compilation.assets[name]; | 
					
						
							|  |  |  | 		}.bind(this)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		var entries = compilation.chunks.filter(function(chunk) { | 
					
						
							|  |  |  | 			return chunk.entry; | 
					
						
							|  |  |  | 		}); | 
					
						
							|  |  |  | 		return callback(null, entries, compilation); | 
					
						
							|  |  |  | 	}.bind(this)); | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-12 04:52:02 +08:00
										 |  |  | Compiler.prototype.purgeInputFileSystem = function() { | 
					
						
							|  |  |  | 	if(this.inputFileSystem && this.inputFileSystem.purge) | 
					
						
							|  |  |  | 		this.inputFileSystem.purge(); | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-01-31 01:49:25 +08:00
										 |  |  | Compiler.prototype.emitAssets = function(compilation, callback) { | 
					
						
							| 
									
										
										
										
											2014-03-12 01:42:51 +08:00
										 |  |  | 	var outputPath; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-01-31 01:49:25 +08:00
										 |  |  | 	this.applyPluginsAsync("emit", compilation, function(err) { | 
					
						
							| 
									
										
										
										
											2014-05-13 13:31:43 +08:00
										 |  |  | 		if(err) return callback(err); | 
					
						
							| 
									
										
										
										
											2014-08-22 19:51:24 +08:00
										 |  |  | 		outputPath = compilation.getPath(this.outputPath); | 
					
						
							| 
									
										
										
										
											2014-03-12 01:42:51 +08:00
										 |  |  | 		this.outputFileSystem.mkdirp(outputPath, emitFiles.bind(this)); | 
					
						
							| 
									
										
										
										
											2013-01-31 01:49:25 +08:00
										 |  |  | 	}.bind(this)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	function emitFiles(err) { | 
					
						
							|  |  |  | 		if(err) return callback(err); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		require("async").forEach(Object.keys(compilation.assets), function(file, callback) { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-03-31 14:45:45 +08:00
										 |  |  | 			var targetFile = file; | 
					
						
							| 
									
										
										
										
											2015-04-24 05:55:50 +08:00
										 |  |  | 			var queryStringIdx = targetFile.indexOf("?"); | 
					
						
							| 
									
										
										
										
											2014-03-31 14:45:45 +08:00
										 |  |  | 			if(queryStringIdx >= 0) { | 
					
						
							|  |  |  | 				targetFile = targetFile.substr(0, queryStringIdx); | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2015-01-05 21:30:18 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			if(targetFile.match(/\/|\\/)) { | 
					
						
							|  |  |  | 				var dir = path.dirname(targetFile); | 
					
						
							| 
									
										
										
										
											2014-03-11 22:39:46 +08:00
										 |  |  | 				this.outputFileSystem.mkdirp(this.outputFileSystem.join(outputPath, dir), writeOut.bind(this)); | 
					
						
							| 
									
										
										
										
											2013-01-31 01:49:25 +08:00
										 |  |  | 			} else writeOut.call(this); | 
					
						
							| 
									
										
										
										
											2015-07-13 06:20:09 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-01-31 01:49:25 +08:00
										 |  |  | 			function writeOut(err) { | 
					
						
							|  |  |  | 				if(err) return callback(err); | 
					
						
							| 
									
										
										
										
											2014-03-31 14:45:45 +08:00
										 |  |  | 				var targetPath = this.outputFileSystem.join(outputPath, targetFile); | 
					
						
							| 
									
										
										
										
											2013-05-08 19:28:54 +08:00
										 |  |  | 				var source = compilation.assets[file]; | 
					
						
							|  |  |  | 				if(source.existsAt === targetPath) { | 
					
						
							|  |  |  | 					source.emitted = false; | 
					
						
							|  |  |  | 					return callback(); | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				var content = source.source(); | 
					
						
							| 
									
										
										
										
											2013-01-31 01:49:25 +08:00
										 |  |  | 				if(!Buffer.isBuffer(content)) | 
					
						
							|  |  |  | 					content = new Buffer(content, "utf-8"); | 
					
						
							| 
									
										
										
										
											2013-05-08 19:28:54 +08:00
										 |  |  | 				source.existsAt = targetPath; | 
					
						
							|  |  |  | 				source.emitted = true; | 
					
						
							|  |  |  | 				this.outputFileSystem.writeFile(targetPath, content, callback); | 
					
						
							| 
									
										
										
										
											2015-04-24 05:55:50 +08:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2013-01-31 01:49:25 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		}.bind(this), function(err) { | 
					
						
							|  |  |  | 			if(err) return callback(err); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			afterEmit.call(this); | 
					
						
							|  |  |  | 		}.bind(this)); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	function afterEmit() { | 
					
						
							|  |  |  | 		this.applyPluginsAsync("after-emit", compilation, function(err) { | 
					
						
							|  |  |  | 			if(err) return callback(err); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			return callback(); | 
					
						
							|  |  |  | 		}); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-05-31 18:22:40 +08:00
										 |  |  | Compiler.prototype.emitRecords = function emitRecords(callback) { | 
					
						
							|  |  |  | 	if(!this.recordsOutputPath) return callback(); | 
					
						
							| 
									
										
										
										
											2013-06-10 20:25:54 +08:00
										 |  |  | 	var idx1 = this.recordsOutputPath.lastIndexOf("/"); | 
					
						
							|  |  |  | 	var idx2 = this.recordsOutputPath.lastIndexOf("\\"); | 
					
						
							|  |  |  | 	var recordsOutputPathDirectory = null; | 
					
						
							|  |  |  | 	if(idx1 > idx2) recordsOutputPathDirectory = this.recordsOutputPath.substr(0, idx1); | 
					
						
							|  |  |  | 	if(idx1 < idx2) recordsOutputPathDirectory = this.recordsOutputPath.substr(0, idx2); | 
					
						
							|  |  |  | 	if(!recordsOutputPathDirectory) return writeFile.call(this); | 
					
						
							|  |  |  | 	this.outputFileSystem.mkdirp(recordsOutputPathDirectory, function(err) { | 
					
						
							|  |  |  | 		if(err) return callback(err); | 
					
						
							| 
									
										
										
										
											2015-04-24 05:55:50 +08:00
										 |  |  | 		writeFile.call(this); | 
					
						
							| 
									
										
										
										
											2013-06-10 20:25:54 +08:00
										 |  |  | 	}.bind(this)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	function writeFile() { | 
					
						
							|  |  |  | 		this.outputFileSystem.writeFile(this.recordsOutputPath, JSON.stringify(this.records, undefined, 2), callback); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2013-05-31 18:22:40 +08:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Compiler.prototype.readRecords = function readRecords(callback) { | 
					
						
							|  |  |  | 	if(!this.recordsInputPath) { | 
					
						
							|  |  |  | 		this.records = {}; | 
					
						
							|  |  |  | 		return callback(); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	this.inputFileSystem.stat(this.recordsInputPath, function(err) { | 
					
						
							|  |  |  | 		// It doesn't exist
 | 
					
						
							|  |  |  | 		// We can ignore this.
 | 
					
						
							|  |  |  | 		if(err) return callback(); | 
					
						
							| 
									
										
										
										
											2013-06-10 20:25:54 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-05-31 18:22:40 +08:00
										 |  |  | 		this.inputFileSystem.readFile(this.recordsInputPath, function(err, content) { | 
					
						
							|  |  |  | 			if(err) return callback(err); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			try { | 
					
						
							|  |  |  | 				this.records = JSON.parse(content); | 
					
						
							|  |  |  | 			} catch(e) { | 
					
						
							|  |  |  | 				e.message = "Cannot parse records: " + e.message; | 
					
						
							|  |  |  | 				return callback(e); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			return callback(); | 
					
						
							|  |  |  | 		}.bind(this)); | 
					
						
							|  |  |  | 	}.bind(this)); | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-01-31 01:49:25 +08:00
										 |  |  | Compiler.prototype.createChildCompiler = function(compilation, compilerName, outputOptions) { | 
					
						
							|  |  |  | 	var childCompiler = new Compiler(); | 
					
						
							|  |  |  | 	for(var name in this._plugins) { | 
					
						
							| 
									
										
										
										
											2014-06-03 03:23:53 +08:00
										 |  |  | 		if(["make", "compile", "emit", "after-emit", "invalid", "done", "this-compilation"].indexOf(name) < 0) | 
					
						
							| 
									
										
										
										
											2013-01-31 01:49:25 +08:00
										 |  |  | 			childCompiler._plugins[name] = this._plugins[name].slice(); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	childCompiler.name = compilerName; | 
					
						
							|  |  |  | 	childCompiler.outputPath = this.outputPath; | 
					
						
							|  |  |  | 	childCompiler.inputFileSystem = this.inputFileSystem; | 
					
						
							|  |  |  | 	childCompiler.outputFileSystem = null; | 
					
						
							|  |  |  | 	childCompiler.resolvers = this.resolvers; | 
					
						
							|  |  |  | 	childCompiler.parser = this.parser; | 
					
						
							|  |  |  | 	childCompiler.fileTimestamps = this.fileTimestamps; | 
					
						
							|  |  |  | 	childCompiler.contextTimestamps = this.contextTimestamps; | 
					
						
							| 
									
										
										
										
											2013-06-20 18:04:31 +08:00
										 |  |  | 	if(!this.records[compilerName]) this.records[compilerName] = []; | 
					
						
							|  |  |  | 	this.records[compilerName].push(childCompiler.records = {}); | 
					
						
							| 
									
										
										
										
											2015-01-18 06:43:25 +08:00
										 |  |  | 	childCompiler.options = Object.create(this.options); | 
					
						
							|  |  |  | 	childCompiler.options.output = Object.create(childCompiler.options.output); | 
					
						
							| 
									
										
										
										
											2015-04-24 05:55:50 +08:00
										 |  |  | 	for(name in outputOptions) { | 
					
						
							| 
									
										
										
										
											2013-01-31 01:49:25 +08:00
										 |  |  | 		childCompiler.options.output[name] = outputOptions[name]; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	childCompiler.parentCompilation = compilation; | 
					
						
							|  |  |  | 	return childCompiler; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-02-04 22:58:04 +08:00
										 |  |  | Compiler.prototype.isChild = function() { | 
					
						
							|  |  |  | 	return !!this.parentCompilation; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-01-31 01:49:25 +08:00
										 |  |  | Compiler.prototype.createCompilation = function() { | 
					
						
							|  |  |  | 	return new Compilation(this); | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Compiler.prototype.newCompilation = function(params) { | 
					
						
							|  |  |  | 	var compilation = this.createCompilation(); | 
					
						
							|  |  |  | 	compilation.fileTimestamps = this.fileTimestamps; | 
					
						
							|  |  |  | 	compilation.contextTimestamps = this.contextTimestamps; | 
					
						
							|  |  |  | 	compilation.name = this.name; | 
					
						
							| 
									
										
										
										
											2013-05-31 18:22:40 +08:00
										 |  |  | 	compilation.records = this.records; | 
					
						
							| 
									
										
										
										
											2014-06-03 03:23:53 +08:00
										 |  |  | 	this.applyPlugins("this-compilation", compilation, params); | 
					
						
							| 
									
										
										
										
											2013-01-31 01:49:25 +08:00
										 |  |  | 	this.applyPlugins("compilation", compilation, params); | 
					
						
							|  |  |  | 	return compilation; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Compiler.prototype.createNormalModuleFactory = function() { | 
					
						
							| 
									
										
										
										
											2013-02-04 20:59:43 +08:00
										 |  |  | 	var normalModuleFactory = new NormalModuleFactory(this.options.context, this.resolvers, this.parser, this.options.module || {}); | 
					
						
							| 
									
										
										
										
											2013-01-31 01:49:25 +08:00
										 |  |  | 	this.applyPlugins("normal-module-factory", normalModuleFactory); | 
					
						
							|  |  |  | 	return normalModuleFactory; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Compiler.prototype.createContextModuleFactory = function() { | 
					
						
							|  |  |  | 	var contextModuleFactory = new ContextModuleFactory(this.resolvers, this.inputFileSystem); | 
					
						
							|  |  |  | 	this.applyPlugins("context-module-factory", contextModuleFactory); | 
					
						
							|  |  |  | 	return contextModuleFactory; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Compiler.prototype.newCompilationParams = function() { | 
					
						
							|  |  |  | 	var params = { | 
					
						
							|  |  |  | 		normalModuleFactory: this.createNormalModuleFactory(), | 
					
						
							|  |  |  | 		contextModuleFactory: this.createContextModuleFactory() | 
					
						
							|  |  |  | 	}; | 
					
						
							|  |  |  | 	return params; | 
					
						
							| 
									
										
										
										
											2014-06-25 00:53:32 +08:00
										 |  |  | }; | 
					
						
							| 
									
										
										
										
											2013-01-31 01:49:25 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | Compiler.prototype.compile = function(callback) { | 
					
						
							|  |  |  | 	var params = this.newCompilationParams(); | 
					
						
							|  |  |  | 	this.applyPlugins("compile", params); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	var compilation = this.newCompilation(params); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-05-13 19:34:00 +08:00
										 |  |  | 	this.applyPluginsParallel("make", compilation, function(err) { | 
					
						
							| 
									
										
										
										
											2013-02-04 21:44:34 +08:00
										 |  |  | 		if(err) return callback(err); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-01-31 01:49:25 +08:00
										 |  |  | 		compilation.seal(function(err) { | 
					
						
							|  |  |  | 			if(err) return callback(err); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			this.applyPluginsAsync("after-compile", compilation, function(err) { | 
					
						
							|  |  |  | 				if(err) return callback(err); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				return callback(null, compilation); | 
					
						
							|  |  |  | 			}); | 
					
						
							|  |  |  | 		}.bind(this)); | 
					
						
							|  |  |  | 	}.bind(this)); | 
					
						
							| 
									
										
										
										
											2014-05-13 13:31:43 +08:00
										 |  |  | }; |