| 
									
										
										
										
											2012-03-12 04:50:55 +08:00
										 |  |  | /* | 
					
						
							|  |  |  | 	MIT License http://www.opensource.org/licenses/mit-license.php
 | 
					
						
							|  |  |  | 	Author Tobias Koppers @sokra | 
					
						
							|  |  |  | */ | 
					
						
							| 
									
										
										
										
											2018-07-30 23:08:51 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-02 03:19:00 +08:00
										 |  |  | "use strict"; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-30 23:08:51 +08:00
										 |  |  | const webpackOptionsSchema = require("../schemas/WebpackOptions.json"); | 
					
						
							| 
									
										
										
										
											2017-01-02 03:19:00 +08:00
										 |  |  | const Compiler = require("./Compiler"); | 
					
						
							|  |  |  | const MultiCompiler = require("./MultiCompiler"); | 
					
						
							|  |  |  | const WebpackOptionsApply = require("./WebpackOptionsApply"); | 
					
						
							| 
									
										
										
										
											2020-02-17 17:27:46 +08:00
										 |  |  | const { | 
					
						
							|  |  |  | 	applyWebpackOptionsDefaults, | 
					
						
							|  |  |  | 	applyWebpackOptionsBaseDefaults | 
					
						
							|  |  |  | } = require("./config/defaults"); | 
					
						
							|  |  |  | const { getNormalizedWebpackOptions } = require("./config/normalization"); | 
					
						
							| 
									
										
										
										
											2018-07-30 23:08:51 +08:00
										 |  |  | const NodeEnvironmentPlugin = require("./node/NodeEnvironmentPlugin"); | 
					
						
							| 
									
										
										
										
											2019-08-08 18:44:45 +08:00
										 |  |  | const validateSchema = require("./validateSchema"); | 
					
						
							| 
									
										
										
										
											2018-02-27 01:22:25 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-19 19:05:22 +08:00
										 |  |  | /** @typedef {import("../declarations/WebpackOptions").WebpackOptions} WebpackOptions */ | 
					
						
							| 
									
										
										
										
											2019-11-08 18:13:16 +08:00
										 |  |  | /** @typedef {import("./Compiler")} Compiler */ | 
					
						
							|  |  |  | /** @typedef {import("./Compiler").WatchOptions} WatchOptions */ | 
					
						
							|  |  |  | /** @typedef {import("./MultiCompiler")} MultiCompiler */ | 
					
						
							| 
									
										
										
										
											2018-12-10 18:34:59 +08:00
										 |  |  | /** @typedef {import("./MultiStats")} MultiStats */ | 
					
						
							| 
									
										
										
										
											2018-09-27 13:22:19 +08:00
										 |  |  | /** @typedef {import("./Stats")} Stats */ | 
					
						
							| 
									
										
										
										
											2018-09-19 19:05:22 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-09 21:26:35 +08:00
										 |  |  | /** | 
					
						
							| 
									
										
										
										
											2018-12-10 18:34:59 +08:00
										 |  |  |  * @template T | 
					
						
							|  |  |  |  * @callback Callback | 
					
						
							| 
									
										
										
										
											2018-12-09 21:26:35 +08:00
										 |  |  |  * @param {Error=} err | 
					
						
							| 
									
										
										
										
											2018-12-10 18:34:59 +08:00
										 |  |  |  * @param {T=} stats | 
					
						
							| 
									
										
										
										
											2018-12-09 21:26:35 +08:00
										 |  |  |  * @returns {void} | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /** | 
					
						
							|  |  |  |  * @param {WebpackOptions[]} childOptions options array | 
					
						
							|  |  |  |  * @returns {MultiCompiler} a multi-compiler | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | const createMultiCompiler = childOptions => { | 
					
						
							|  |  |  | 	const compilers = childOptions.map(options => createCompiler(options)); | 
					
						
							|  |  |  | 	const compiler = new MultiCompiler(compilers); | 
					
						
							|  |  |  | 	for (const childCompiler of compilers) { | 
					
						
							|  |  |  | 		if (childCompiler.options.dependencies) { | 
					
						
							|  |  |  | 			compiler.setDependencies( | 
					
						
							|  |  |  | 				childCompiler, | 
					
						
							|  |  |  | 				childCompiler.options.dependencies | 
					
						
							|  |  |  | 			); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return compiler; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-19 19:05:22 +08:00
										 |  |  | /** | 
					
						
							| 
									
										
										
										
											2020-02-17 17:27:46 +08:00
										 |  |  |  * @param {WebpackOptions} rawOptions options object | 
					
						
							| 
									
										
										
										
											2018-12-09 21:26:35 +08:00
										 |  |  |  * @returns {Compiler} a compiler | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2020-02-17 17:27:46 +08:00
										 |  |  | const createCompiler = rawOptions => { | 
					
						
							|  |  |  | 	const options = getNormalizedWebpackOptions(rawOptions); | 
					
						
							|  |  |  | 	applyWebpackOptionsBaseDefaults(options); | 
					
						
							| 
									
										
										
										
											2018-12-09 21:26:35 +08:00
										 |  |  | 	const compiler = new Compiler(options.context); | 
					
						
							|  |  |  | 	compiler.options = options; | 
					
						
							| 
									
										
										
										
											2019-07-24 16:51:04 +08:00
										 |  |  | 	new NodeEnvironmentPlugin({ | 
					
						
							|  |  |  | 		infrastructureLogging: options.infrastructureLogging | 
					
						
							|  |  |  | 	}).apply(compiler); | 
					
						
							| 
									
										
										
										
											2018-12-09 21:26:35 +08:00
										 |  |  | 	if (Array.isArray(options.plugins)) { | 
					
						
							|  |  |  | 		for (const plugin of options.plugins) { | 
					
						
							|  |  |  | 			if (typeof plugin === "function") { | 
					
						
							|  |  |  | 				plugin.call(compiler, compiler); | 
					
						
							|  |  |  | 			} else { | 
					
						
							|  |  |  | 				plugin.apply(compiler); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2020-02-17 17:27:46 +08:00
										 |  |  | 	applyWebpackOptionsDefaults(options); | 
					
						
							| 
									
										
										
										
											2018-12-09 21:26:35 +08:00
										 |  |  | 	compiler.hooks.environment.call(); | 
					
						
							|  |  |  | 	compiler.hooks.afterEnvironment.call(); | 
					
						
							| 
									
										
										
										
											2020-02-17 17:27:46 +08:00
										 |  |  | 	new WebpackOptionsApply().process(options, compiler); | 
					
						
							|  |  |  | 	compiler.hooks.initialize.call(); | 
					
						
							| 
									
										
										
										
											2018-12-09 21:26:35 +08:00
										 |  |  | 	return compiler; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /** | 
					
						
							| 
									
										
										
										
											2020-04-21 14:54:59 +08:00
										 |  |  |  * @callback WebpackFunctionSingle | 
					
						
							|  |  |  |  * @param {WebpackOptions} options options object | 
					
						
							|  |  |  |  * @param {Callback<Stats>=} callback callback | 
					
						
							|  |  |  |  * @returns {Compiler} the compiler object | 
					
						
							| 
									
										
										
										
											2018-09-19 19:05:22 +08:00
										 |  |  |  */ | 
					
						
							| 
									
										
										
										
											2020-04-21 14:54:59 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | /** | 
					
						
							|  |  |  |  * @callback WebpackFunctionMulti | 
					
						
							|  |  |  |  * @param {WebpackOptions[]} options options objects | 
					
						
							|  |  |  |  * @param {Callback<MultiStats>=} callback callback | 
					
						
							|  |  |  |  * @returns {MultiCompiler} the multi compiler object | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | const webpack = /** @type {WebpackFunctionSingle & WebpackFunctionMulti} */ (( | 
					
						
							|  |  |  | 	options, | 
					
						
							|  |  |  | 	callback | 
					
						
							|  |  |  | ) => { | 
					
						
							| 
									
										
										
										
											2020-09-28 16:51:12 +08:00
										 |  |  | 	const create = () => { | 
					
						
							|  |  |  | 		validateSchema(webpackOptionsSchema, options); | 
					
						
							|  |  |  | 		/** @type {MultiCompiler|Compiler} */ | 
					
						
							|  |  |  | 		let compiler; | 
					
						
							|  |  |  | 		let watch = false; | 
					
						
							|  |  |  | 		/** @type {WatchOptions|WatchOptions[]} */ | 
					
						
							|  |  |  | 		let watchOptions; | 
					
						
							|  |  |  | 		if (Array.isArray(options)) { | 
					
						
							|  |  |  | 			/** @type {MultiCompiler} */ | 
					
						
							|  |  |  | 			compiler = createMultiCompiler(options); | 
					
						
							|  |  |  | 			watch = options.some(options => options.watch); | 
					
						
							|  |  |  | 			watchOptions = options.map(options => options.watchOptions || {}); | 
					
						
							| 
									
										
										
										
											2018-12-09 21:26:35 +08:00
										 |  |  | 		} else { | 
					
						
							| 
									
										
										
										
											2020-09-28 16:51:12 +08:00
										 |  |  | 			/** @type {Compiler} */ | 
					
						
							|  |  |  | 			compiler = createCompiler(options); | 
					
						
							|  |  |  | 			watch = options.watch; | 
					
						
							|  |  |  | 			watchOptions = options.watchOptions || {}; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		return { compiler, watch, watchOptions }; | 
					
						
							|  |  |  | 	}; | 
					
						
							|  |  |  | 	if (callback) { | 
					
						
							|  |  |  | 		try { | 
					
						
							|  |  |  | 			const { compiler, watch, watchOptions } = create(); | 
					
						
							|  |  |  | 			if (watch) { | 
					
						
							|  |  |  | 				compiler.watch(watchOptions, callback); | 
					
						
							|  |  |  | 			} else { | 
					
						
							|  |  |  | 				compiler.run((err, stats) => { | 
					
						
							|  |  |  | 					compiler.close(err2 => { | 
					
						
							|  |  |  | 						callback(err || err2, stats); | 
					
						
							|  |  |  | 					}); | 
					
						
							| 
									
										
										
										
											2018-12-09 21:26:35 +08:00
										 |  |  | 				}); | 
					
						
							| 
									
										
										
										
											2020-09-28 16:51:12 +08:00
										 |  |  | 			} | 
					
						
							|  |  |  | 			return compiler; | 
					
						
							|  |  |  | 		} catch (err) { | 
					
						
							|  |  |  | 			process.nextTick(() => callback(err)); | 
					
						
							|  |  |  | 			return null; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 		const { compiler, watch } = create(); | 
					
						
							|  |  |  | 		if (watch) { | 
					
						
							|  |  |  | 			throw new Error( | 
					
						
							|  |  |  | 				"A 'callback' argument need to be provided when the 'watch' option is set" | 
					
						
							|  |  |  | 			); | 
					
						
							| 
									
										
										
										
											2018-12-09 21:26:35 +08:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2020-09-28 16:51:12 +08:00
										 |  |  | 		return compiler; | 
					
						
							| 
									
										
										
										
											2012-10-20 21:08:12 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2020-04-21 14:54:59 +08:00
										 |  |  | }); | 
					
						
							| 
									
										
										
										
											2017-11-08 18:32:05 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-09 21:26:35 +08:00
										 |  |  | module.exports = webpack; |