| 
									
										
										
										
											2012-03-12 04:50:55 +08:00
										 |  |  | /* | 
					
						
							|  |  |  | 	MIT License http://www.opensource.org/licenses/mit-license.php
 | 
					
						
							|  |  |  | 	Author Tobias Koppers @sokra | 
					
						
							|  |  |  | */ | 
					
						
							| 
									
										
										
										
											2012-03-10 20:11:23 +08:00
										 |  |  | var buildDeps = require("./buildDeps"); | 
					
						
							|  |  |  | var path = require("path"); | 
					
						
							|  |  |  | var writeChunk = require("./writeChunk"); | 
					
						
							|  |  |  | var fs = require("fs"); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-01 23:46:26 +08:00
										 |  |  | var HASH_REGEXP = /\[hash\]/i; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-10 20:11:23 +08:00
										 |  |  | var templateAsync = require("fs").readFileSync(path.join(__dirname, "templateAsync.js")); | 
					
						
							|  |  |  | var templateSingle = require("fs").readFileSync(path.join(__dirname, "templateSingle.js")); | 
					
						
							|  |  |  | /* | 
					
						
							|  |  |  | 	webpack(context, moduleName, options, callback); | 
					
						
							|  |  |  | 	webpack(context, moduleName, callback); | 
					
						
							|  |  |  | 	webpack(absoluteModulePath, options, callback); | 
					
						
							|  |  |  | 	webpack(absoluteModulePath, callback); | 
					
						
							| 
									
										
										
										
											2012-03-12 04:50:55 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-10 20:11:23 +08:00
										 |  |  | 	callback: function(err, source / stats) | 
					
						
							|  |  |  | 	  source if options.output is not set | 
					
						
							|  |  |  | 	  else stats json | 
					
						
							| 
									
										
										
										
											2012-03-12 04:50:55 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-10 20:11:23 +08:00
										 |  |  | 	options: | 
					
						
							|  |  |  | 	- outputJsonpFunction | 
					
						
							|  |  |  | 	   JSONP function used to load chunks | 
					
						
							|  |  |  | 	- scriptSrcPrefix | 
					
						
							|  |  |  | 	   Path from where chunks are loaded | 
					
						
							|  |  |  | 	- outputDirectory | 
					
						
							|  |  |  | 	   write files to this directory (absolute path) | 
					
						
							|  |  |  | 	- output | 
					
						
							|  |  |  | 	   write first chunk to this file | 
					
						
							|  |  |  | 	- outputPostfix | 
					
						
							|  |  |  | 	   write chunks to files named chunkId plus outputPostfix | 
					
						
							|  |  |  | 	- libary | 
					
						
							|  |  |  | 	   exports of input file are stored in this variable | 
					
						
							|  |  |  | 	- minimize | 
					
						
							|  |  |  | 	   minimize outputs with uglify-js | 
					
						
							|  |  |  | 	- includeFilenames | 
					
						
							|  |  |  | 	   add absolute filenames of input files as comments | 
					
						
							| 
									
										
										
										
											2012-03-16 20:59:19 +08:00
										 |  |  | 	- resolve.alias (object) | 
					
						
							|  |  |  | 	   replace a module. ex {"old-module": "new-module"} | 
					
						
							|  |  |  | 	- resolve.extensions (object) | 
					
						
							| 
									
										
										
										
											2012-03-27 06:00:32 +08:00
										 |  |  | 	   possible extensions for files | 
					
						
							| 
									
										
										
										
											2012-03-16 20:59:19 +08:00
										 |  |  | 	- resolve.paths (array) | 
					
						
							|  |  |  | 	   search paths | 
					
						
							| 
									
										
										
										
											2012-03-27 06:00:32 +08:00
										 |  |  | 	- resolve.loaders (array) | 
					
						
							|  |  |  | 	   extension to loader mappings | 
					
						
							|  |  |  | 	   {test: /\.extension$/, loader: "myloader"} | 
					
						
							|  |  |  | 	   loads files that matches the RegExp to the loader if no other loader set | 
					
						
							| 
									
										
										
										
											2012-03-16 20:59:19 +08:00
										 |  |  | 	- parse.overwrites (object) | 
					
						
							|  |  |  | 	   free module varables which are replaced with a module | 
					
						
							|  |  |  | 	   ex. { "$": "jquery" } | 
					
						
							| 
									
										
										
										
											2012-03-10 20:11:23 +08:00
										 |  |  | */ | 
					
						
							|  |  |  | module.exports = function(context, moduleName, options, callback) { | 
					
						
							|  |  |  | 	if(typeof moduleName === "object") { | 
					
						
							|  |  |  | 		callback = options; | 
					
						
							|  |  |  | 		options = moduleName; | 
					
						
							|  |  |  | 		moduleName = "./" + path.basename(context); | 
					
						
							|  |  |  | 		context = path.dirname(context); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if(typeof moduleName === "function") { | 
					
						
							|  |  |  | 		callback = moduleName; | 
					
						
							|  |  |  | 		options = {}; | 
					
						
							|  |  |  | 		moduleName = "./" + path.basename(context); | 
					
						
							|  |  |  | 		context = path.dirname(context); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if(!callback) { | 
					
						
							|  |  |  | 		callback = options; | 
					
						
							|  |  |  | 		options = {}; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2012-05-02 03:33:59 +08:00
										 |  |  | 	if(!options.events) options.events = new (require("events").EventEmitter)(); | 
					
						
							|  |  |  | 	if(options.watch) { | 
					
						
							|  |  |  | 		var fs = require("fs"); | 
					
						
							|  |  |  | 		var watchers = []; | 
					
						
							|  |  |  | 		var isRunning = true; | 
					
						
							|  |  |  | 		var runAgain = false; | 
					
						
							|  |  |  | 		function startAgain() { | 
					
						
							|  |  |  | 			watchers.forEach(function(watcher) { | 
					
						
							|  |  |  | 				watcher.close(); | 
					
						
							|  |  |  | 			}); | 
					
						
							|  |  |  | 			watchers.length = 0; | 
					
						
							|  |  |  | 			isRunning = true; | 
					
						
							|  |  |  | 			setTimeout(function() { | 
					
						
							|  |  |  | 				runAgain = false; | 
					
						
							|  |  |  | 				webpack(context, moduleName, options, callback); | 
					
						
							|  |  |  | 			}, 200); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		function change() { | 
					
						
							|  |  |  | 			if(isRunning) | 
					
						
							|  |  |  | 				runAgain = true; | 
					
						
							|  |  |  | 			else | 
					
						
							|  |  |  | 				startAgain() | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		options.events.on("module", function(module, filename) { | 
					
						
							|  |  |  | 			if(!filename) return; | 
					
						
							|  |  |  | 			var w = fs.watch(filename, function() { | 
					
						
							|  |  |  | 				change(); | 
					
						
							|  |  |  | 			}); | 
					
						
							|  |  |  | 		}); | 
					
						
							|  |  |  | 		options.events.on("context", function(module, dirname) { | 
					
						
							|  |  |  | 			if(!dirname) return; | 
					
						
							|  |  |  | 			fs.watch(dirname, function() { | 
					
						
							|  |  |  | 				change(); | 
					
						
							|  |  |  | 			}); | 
					
						
							|  |  |  | 		}); | 
					
						
							|  |  |  | 		options.events.on("bundle", function(stats) { | 
					
						
							|  |  |  | 			isRunning = false; | 
					
						
							|  |  |  | 			if(runAgain) | 
					
						
							|  |  |  | 				startAgain(); | 
					
						
							|  |  |  | 		}); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return webpack(context, moduleName, options, callback); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | function webpack(context, moduleName, options, finalCallback) { | 
					
						
							| 
									
										
										
										
											2012-03-15 21:38:55 +08:00
										 |  |  | 	options.parse = options.parse || {}; | 
					
						
							|  |  |  | 	options.parse.overwrites = options.parse.overwrites || {}; | 
					
						
							|  |  |  | 	options.parse.overwrites.process = options.parse.overwrites.process || ("__webpack_process"); | 
					
						
							| 
									
										
										
										
											2012-04-05 20:59:01 +08:00
										 |  |  | 	options.parse.overwrites.module = options.parse.overwrites.module || ("__webpack_module+(module)"); | 
					
						
							| 
									
										
										
										
											2012-03-16 06:01:42 +08:00
										 |  |  | 	options.parse.overwrites.console = options.parse.overwrites.console || ("__webpack_console"); | 
					
						
							|  |  |  | 	options.parse.overwrites.global = options.parse.overwrites.global || ("__webpack_global"); | 
					
						
							| 
									
										
										
										
											2012-04-05 20:59:01 +08:00
										 |  |  | 	options.parse.overwrites.Buffer = options.parse.overwrites.Buffer || ("buffer+.Buffer"); | 
					
						
							|  |  |  | 	options.parse.overwrites["__dirname"] = options.parse.overwrites["__dirname"] || ("__webpack_dirname"); | 
					
						
							|  |  |  | 	options.parse.overwrites["__filename"] = options.parse.overwrites["__filename"] || ("__webpack_filename"); | 
					
						
							| 
									
										
										
										
											2012-03-15 21:38:55 +08:00
										 |  |  | 	options.resolve = options.resolve || {}; | 
					
						
							|  |  |  | 	options.resolve.paths = options.resolve.paths || []; | 
					
						
							| 
									
										
										
										
											2012-03-16 20:59:19 +08:00
										 |  |  | 	options.resolve.paths.push(path.join(path.dirname(__dirname), "buildin")); | 
					
						
							|  |  |  | 	options.resolve.paths.push(path.join(path.dirname(__dirname), "buildin", "web_modules")); | 
					
						
							|  |  |  | 	options.resolve.paths.push(path.join(path.dirname(__dirname), "buildin", "node_modules")); | 
					
						
							| 
									
										
										
										
											2012-03-27 06:00:32 +08:00
										 |  |  | 	options.resolve.paths.push(path.join(path.dirname(__dirname), "node_modules")); | 
					
						
							| 
									
										
										
										
											2012-03-16 20:59:19 +08:00
										 |  |  | 	options.resolve.alias = options.resolve.alias || {}; | 
					
						
							| 
									
										
										
										
											2012-04-03 22:26:08 +08:00
										 |  |  | 	options.resolve.loaders = options.resolve.loaders || []; | 
					
						
							| 
									
										
										
										
											2012-03-27 06:00:32 +08:00
										 |  |  | 	options.resolve.loaders.push({test: /\.coffee$/, loader: "coffee"}); | 
					
						
							|  |  |  | 	options.resolve.loaders.push({test: /\.json$/, loader: "json"}); | 
					
						
							|  |  |  | 	options.resolve.loaders.push({test: /\.jade$/, loader: "jade"}); | 
					
						
							| 
									
										
										
										
											2012-04-07 09:20:45 +08:00
										 |  |  | 	options.resolve.loaders.push({test: /\.css$/, loader: "style!css"}); | 
					
						
							| 
									
										
										
										
											2012-05-04 22:42:38 +08:00
										 |  |  | 	options.resolve.loaders.push({test: /\.less$/, loader: "style!css!val!less"}); | 
					
						
							| 
									
										
										
										
											2012-05-02 20:06:42 +08:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	options.events.emit("task", "create ouput directory"); | 
					
						
							|  |  |  | 	options.events.emit("task", "prepare chunks"); | 
					
						
							|  |  |  | 	options.events.emit("task", "statistics"); | 
					
						
							| 
									
										
										
										
											2012-03-10 20:11:23 +08:00
										 |  |  | 	buildDeps(context, moduleName, options, function(err, depTree) { | 
					
						
							| 
									
										
										
										
											2012-05-02 20:06:42 +08:00
										 |  |  | 		function callback(err, result) { | 
					
						
							|  |  |  | 			options.events.emit("task-end", "statistics"); | 
					
						
							|  |  |  | 			finalCallback(err, result); | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2012-03-10 20:11:23 +08:00
										 |  |  | 		if(err) { | 
					
						
							|  |  |  | 			callback(err); | 
					
						
							|  |  |  | 			return; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		var buffer = []; | 
					
						
							|  |  |  | 		if(options.output) { | 
					
						
							|  |  |  | 			if(!options.outputJsonpFunction) | 
					
						
							|  |  |  | 				options.outputJsonpFunction = "webpackJsonp" + (options.libary  || ""); | 
					
						
							|  |  |  | 			options.scriptSrcPrefix = options.scriptSrcPrefix || ""; | 
					
						
							|  |  |  | 			if(!options.outputDirectory) { | 
					
						
							|  |  |  | 				options.outputDirectory = path.dirname(options.output); | 
					
						
							|  |  |  | 				options.output = path.basename(options.output); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			if(!options.outputPostfix) { | 
					
						
							|  |  |  | 				options.outputPostfix = "." + options.output; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			var fileSizeMap = {}; | 
					
						
							| 
									
										
										
										
											2012-03-14 23:33:46 +08:00
										 |  |  | 			var fileModulesMap = {}; | 
					
						
							| 
									
										
										
										
											2012-05-01 23:46:26 +08:00
										 |  |  | 			var fileWrites = []; | 
					
						
							| 
									
										
										
										
											2012-03-10 20:11:23 +08:00
										 |  |  | 			var chunksCount = 0; | 
					
						
							| 
									
										
										
										
											2012-05-01 23:46:26 +08:00
										 |  |  | 			var chunkIds = Object.keys(depTree.chunks); | 
					
						
							|  |  |  | 			chunkIds.sort(function(a,b) { | 
					
						
							|  |  |  | 				return parseInt(b, 10) - parseInt(a, 10); | 
					
						
							|  |  |  | 			}); | 
					
						
							|  |  |  | 			var hash; | 
					
						
							|  |  |  | 			try { | 
					
						
							|  |  |  | 				hash = new (require("crypto").Hash)("md5"); | 
					
						
							|  |  |  | 				hash.update(JSON.stringify(options.libary || "")); | 
					
						
							|  |  |  | 				hash.update(JSON.stringify(options.outputPostfix)); | 
					
						
							|  |  |  | 				hash.update(JSON.stringify(options.outputJsonpFunction)); | 
					
						
							|  |  |  | 				hash.update(JSON.stringify(options.scriptSrcPrefix)); | 
					
						
							|  |  |  | 				hash.update(templateAsync); | 
					
						
							|  |  |  | 				hash.update(templateSingle); | 
					
						
							|  |  |  | 				hash.update("1"); | 
					
						
							|  |  |  | 			} catch(e) { | 
					
						
							|  |  |  | 				callback(e); | 
					
						
							|  |  |  | 				return; | 
					
						
							|  |  |  | 				hash = null; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			chunkIds.forEach(function(chunkId) { | 
					
						
							| 
									
										
										
										
											2012-03-10 20:11:23 +08:00
										 |  |  | 				var chunk = depTree.chunks[chunkId]; | 
					
						
							| 
									
										
										
										
											2012-05-01 23:46:26 +08:00
										 |  |  | 				if(chunk.empty) return; | 
					
						
							|  |  |  | 				if(chunk.equals !== undefined) return; | 
					
						
							| 
									
										
										
										
											2012-03-10 20:11:23 +08:00
										 |  |  | 				chunksCount++; | 
					
						
							|  |  |  | 				var filename = path.join(options.outputDirectory, | 
					
						
							|  |  |  | 					chunk.id === 0 ? options.output : chunk.id + options.outputPostfix); | 
					
						
							| 
									
										
										
										
											2012-05-01 23:46:26 +08:00
										 |  |  | 				var content = writeChunk(depTree, chunk, options); | 
					
						
							|  |  |  | 				if(hash) hash.update(content); | 
					
						
							| 
									
										
										
										
											2012-03-10 20:11:23 +08:00
										 |  |  | 				buffer = []; | 
					
						
							|  |  |  | 				if(chunk.id === 0) { | 
					
						
							| 
									
										
										
										
											2012-05-01 23:46:26 +08:00
										 |  |  | 					if(hash) | 
					
						
							|  |  |  | 						hash = hash.digest("hex"); | 
					
						
							|  |  |  | 					else | 
					
						
							|  |  |  | 						hash = ""; | 
					
						
							| 
									
										
										
										
											2012-03-10 20:11:23 +08:00
										 |  |  | 					if(options.libary) { | 
					
						
							|  |  |  | 						buffer.push("/******/var "); | 
					
						
							|  |  |  | 						buffer.push(options.libary); | 
					
						
							|  |  |  | 						buffer.push("=\n"); | 
					
						
							|  |  |  | 					} | 
					
						
							| 
									
										
										
										
											2012-05-01 23:46:26 +08:00
										 |  |  | 					if(chunkIds.length > 1) { | 
					
						
							| 
									
										
										
										
											2012-03-10 20:11:23 +08:00
										 |  |  | 						buffer.push(templateAsync); | 
					
						
							|  |  |  | 						buffer.push("/******/({a:"); | 
					
						
							| 
									
										
										
										
											2012-05-01 23:46:26 +08:00
										 |  |  | 						buffer.push(JSON.stringify(options.outputPostfix.replace(HASH_REGEXP, hash))); | 
					
						
							| 
									
										
										
										
											2012-03-10 20:11:23 +08:00
										 |  |  | 						buffer.push(",b:"); | 
					
						
							| 
									
										
										
										
											2012-04-03 22:26:08 +08:00
										 |  |  | 						buffer.push(JSON.stringify(options.outputJsonpFunction)); | 
					
						
							| 
									
										
										
										
											2012-03-10 20:11:23 +08:00
										 |  |  | 						buffer.push(",c:"); | 
					
						
							| 
									
										
										
										
											2012-05-01 23:46:26 +08:00
										 |  |  | 						buffer.push(JSON.stringify(options.scriptSrcPrefix.replace(HASH_REGEXP, hash))); | 
					
						
							| 
									
										
										
										
											2012-03-10 20:11:23 +08:00
										 |  |  | 						buffer.push(",\n"); | 
					
						
							|  |  |  | 					} else { | 
					
						
							|  |  |  | 						buffer.push(templateSingle); | 
					
						
							|  |  |  | 						buffer.push("/******/({\n"); | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 				} else { | 
					
						
							|  |  |  | 					buffer.push("/******/"); | 
					
						
							|  |  |  | 					buffer.push(options.outputJsonpFunction); | 
					
						
							|  |  |  | 					buffer.push("("); | 
					
						
							|  |  |  | 					buffer.push(chunk.id); | 
					
						
							|  |  |  | 					buffer.push(", {\n"); | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2012-05-01 23:46:26 +08:00
										 |  |  | 				buffer.push(content); | 
					
						
							| 
									
										
										
										
											2012-03-10 20:11:23 +08:00
										 |  |  | 				buffer.push("/******/})"); | 
					
						
							|  |  |  | 				buffer = buffer.join(""); | 
					
						
							| 
									
										
										
										
											2012-03-27 06:00:32 +08:00
										 |  |  | 				try { | 
					
						
							|  |  |  | 					if(options.minimize) buffer = uglify(buffer, filename); | 
					
						
							|  |  |  | 				} catch(e) { | 
					
						
							|  |  |  | 					callback(e); | 
					
						
							|  |  |  | 					return; | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2012-05-01 23:46:26 +08:00
										 |  |  | 				fileWrites.push([filename, buffer]); | 
					
						
							| 
									
										
										
										
											2012-03-10 20:11:23 +08:00
										 |  |  | 				fileSizeMap[path.basename(filename)] = buffer.length; | 
					
						
							| 
									
										
										
										
											2012-03-14 23:33:46 +08:00
										 |  |  | 				var modulesArray = []; | 
					
						
							|  |  |  | 				for(var moduleId in chunk.modules) { | 
					
						
							| 
									
										
										
										
											2012-03-15 07:05:29 +08:00
										 |  |  | 					var modu = depTree.modules[moduleId]; | 
					
						
							| 
									
										
										
										
											2012-04-08 03:36:55 +08:00
										 |  |  | 					if(chunk.modules[moduleId] === "include") { | 
					
						
							| 
									
										
										
										
											2012-03-15 07:05:29 +08:00
										 |  |  | 						modulesArray.push({ | 
					
						
							| 
									
										
										
										
											2012-04-08 03:36:55 +08:00
										 |  |  | 							id: modu.realId, | 
					
						
							|  |  |  | 							size: modu.size, | 
					
						
							|  |  |  | 							filename: modu.filename, | 
					
						
							|  |  |  | 							dirname: modu.dirname, | 
					
						
							| 
									
										
										
										
											2012-03-15 07:05:29 +08:00
										 |  |  | 							reasons: modu.reasons}); | 
					
						
							| 
									
										
										
										
											2012-04-08 03:36:55 +08:00
										 |  |  | 					} | 
					
						
							| 
									
										
										
										
											2012-03-14 23:33:46 +08:00
										 |  |  | 				} | 
					
						
							| 
									
										
										
										
											2012-04-08 03:36:55 +08:00
										 |  |  | 				modulesArray.sort(function(a, b) { | 
					
						
							|  |  |  | 					return a.id - b.id; | 
					
						
							|  |  |  | 				}); | 
					
						
							| 
									
										
										
										
											2012-03-14 23:33:46 +08:00
										 |  |  | 				fileModulesMap[path.basename(filename)] = modulesArray; | 
					
						
							| 
									
										
										
										
											2012-05-01 23:46:26 +08:00
										 |  |  | 			}); | 
					
						
							| 
									
										
										
										
											2012-05-02 20:06:42 +08:00
										 |  |  | 			options.events.emit("task-end", "prepare chunks"); | 
					
						
							| 
									
										
										
										
											2012-05-02 03:33:59 +08:00
										 |  |  | 			options.events.emit("start-writing", hash); | 
					
						
							| 
									
										
										
										
											2012-05-01 23:46:26 +08:00
										 |  |  | 			// write files
 | 
					
						
							|  |  |  | 			var remFiles = fileWrites.length; | 
					
						
							|  |  |  | 			var outDir = options.outputDirectory.replace(HASH_REGEXP, hash); | 
					
						
							|  |  |  | 			function createDir(dir, callback) { | 
					
						
							|  |  |  | 				path.exists(dir, function(exists) { | 
					
						
							|  |  |  | 					if(exists) | 
					
						
							|  |  |  | 						callback(); | 
					
						
							|  |  |  | 					else { | 
					
						
							|  |  |  | 						fs.mkdir(dir, function(err) { | 
					
						
							|  |  |  | 							if(err) { | 
					
						
							|  |  |  | 								var parentDir = path.join(dir, ".."); | 
					
						
							|  |  |  | 								if(parentDir == dir) | 
					
						
							|  |  |  | 									return callback(err); | 
					
						
							|  |  |  | 								createDir(parentDir, function(err) { | 
					
						
							|  |  |  | 									if(err) return callback(err); | 
					
						
							|  |  |  | 									fs.mkdir(dir, function(err) { | 
					
						
							|  |  |  | 										if(err) return callback(err); | 
					
						
							|  |  |  | 										callback(); | 
					
						
							|  |  |  | 									}); | 
					
						
							|  |  |  | 								}); | 
					
						
							|  |  |  | 								return; | 
					
						
							|  |  |  | 							} | 
					
						
							|  |  |  | 							callback(); | 
					
						
							|  |  |  | 						}); | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 				}); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			createDir(outDir, function(err) { | 
					
						
							| 
									
										
										
										
											2012-05-02 20:06:42 +08:00
										 |  |  | 				options.events.emit("task-end", "create ouput directory"); | 
					
						
							| 
									
										
										
										
											2012-05-01 23:46:26 +08:00
										 |  |  | 				if(err) return callback(err); | 
					
						
							|  |  |  | 				writeFiles(); | 
					
						
							|  |  |  | 			}); | 
					
						
							|  |  |  | 			function writeFiles() { | 
					
						
							|  |  |  | 				fileWrites.forEach(function(writeAction) { | 
					
						
							| 
									
										
										
										
											2012-05-02 20:06:42 +08:00
										 |  |  | 					options.events.emit("task", "write " + writeAction[0]); | 
					
						
							| 
									
										
										
										
											2012-05-01 23:46:26 +08:00
										 |  |  | 					fs.writeFile(writeAction[0].replace(HASH_REGEXP, hash), writeAction[1], "utf-8", function(err) { | 
					
						
							| 
									
										
										
										
											2012-05-02 20:06:42 +08:00
										 |  |  | 						options.events.emit("task-end", "write " + writeAction[0]); | 
					
						
							| 
									
										
										
										
											2012-05-01 23:46:26 +08:00
										 |  |  | 						if(err) throw err; | 
					
						
							|  |  |  | 						remFiles--; | 
					
						
							|  |  |  | 						if(remFiles === 0) | 
					
						
							|  |  |  | 							writingFinished(); | 
					
						
							|  |  |  | 					}); | 
					
						
							|  |  |  | 				}); | 
					
						
							| 
									
										
										
										
											2012-03-10 20:11:23 +08:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2012-05-01 23:46:26 +08:00
										 |  |  | 			function writingFinished() { | 
					
						
							|  |  |  | 				// Stats
 | 
					
						
							|  |  |  | 				buffer = {}; | 
					
						
							|  |  |  | 				buffer.hash = hash; | 
					
						
							|  |  |  | 				buffer.chunkCount = chunksCount; | 
					
						
							|  |  |  | 				buffer.modulesCount = Object.keys(depTree.modules).length; | 
					
						
							|  |  |  | 				var sum = 0; | 
					
						
							|  |  |  | 				for(var chunkId in depTree.chunks) { | 
					
						
							|  |  |  | 					for(var moduleId in depTree.chunks[chunkId].modules) { | 
					
						
							|  |  |  | 						if(depTree.chunks[chunkId].modules[moduleId] === "include") | 
					
						
							|  |  |  | 							sum++; | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				buffer.modulesIncludingDuplicates = sum; | 
					
						
							|  |  |  | 				buffer.modulesPerChunk = Math.round(sum / chunksCount*10)/10; | 
					
						
							|  |  |  | 				sum = 0; | 
					
						
							|  |  |  | 				for(var moduleId in depTree.chunks[0].modules) { | 
					
						
							|  |  |  | 					if(depTree.chunks[0].modules[moduleId] === "include") | 
					
						
							| 
									
										
										
										
											2012-03-10 20:11:23 +08:00
										 |  |  | 						sum++; | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2012-05-01 23:46:26 +08:00
										 |  |  | 				buffer.modulesFirstChunk = sum; | 
					
						
							|  |  |  | 				buffer.fileSizes = fileSizeMap; | 
					
						
							|  |  |  | 				buffer.warnings = depTree.warnings; | 
					
						
							|  |  |  | 				buffer.errors = depTree.errors; | 
					
						
							|  |  |  | 				buffer.fileModules = fileModulesMap; | 
					
						
							| 
									
										
										
										
											2012-05-02 03:33:59 +08:00
										 |  |  | 				options.events.emit("bundle", buffer); | 
					
						
							| 
									
										
										
										
											2012-05-01 23:46:26 +08:00
										 |  |  | 				callback(null, buffer); | 
					
						
							| 
									
										
										
										
											2012-03-10 20:11:23 +08:00
										 |  |  | 			} | 
					
						
							|  |  |  | 		} else { | 
					
						
							|  |  |  | 			if(options.libary) { | 
					
						
							|  |  |  | 				buffer.push("/******/var "); | 
					
						
							|  |  |  | 				buffer.push(options.libary); | 
					
						
							|  |  |  | 				buffer.push("=\n"); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			buffer.push(templateSingle); | 
					
						
							|  |  |  | 			buffer.push("/******/({\n"); | 
					
						
							|  |  |  | 			buffer.push(writeChunk(depTree, options)); | 
					
						
							|  |  |  | 			buffer.push("/******/})"); | 
					
						
							|  |  |  | 			buffer = buffer.join(""); | 
					
						
							| 
									
										
										
										
											2012-03-27 06:00:32 +08:00
										 |  |  | 			try { | 
					
						
							|  |  |  | 				if(options.minimize) buffer = uglify(buffer, "output"); | 
					
						
							|  |  |  | 				callback(null, buffer); | 
					
						
							|  |  |  | 			} catch(e) { | 
					
						
							|  |  |  | 				callback(e); | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2012-03-10 20:11:23 +08:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	}); | 
					
						
							| 
									
										
										
										
											2012-05-02 03:33:59 +08:00
										 |  |  | 	return options.events; | 
					
						
							| 
									
										
										
										
											2012-03-10 20:11:23 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | function uglify(input, filename) { | 
					
						
							|  |  |  | 	var uglify = require("uglify-js"); | 
					
						
							|  |  |  | 	try { | 
					
						
							|  |  |  | 		source = uglify.parser.parse(input); | 
					
						
							|  |  |  | 		source = uglify.uglify.ast_mangle(source); | 
					
						
							|  |  |  | 		source = uglify.uglify.ast_squeeze(source); | 
					
						
							|  |  |  | 		source = uglify.uglify.gen_code(source); | 
					
						
							|  |  |  | 	} catch(e) { | 
					
						
							| 
									
										
										
										
											2012-03-27 06:00:32 +08:00
										 |  |  | 		throw new Error(filename + " @ Line " + e.line + ", Col " + e.col + ", " + e.message); | 
					
						
							| 
									
										
										
										
											2012-03-10 20:11:23 +08:00
										 |  |  | 		return input; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return source; | 
					
						
							|  |  |  | } |