2 MIT License http://www.opensource.org/licenses/mit-license.php
3 Author Tobias Koppers @sokra
8 const util = require("util");
9 const webpackOptionsSchemaCheck = require("../schemas/WebpackOptions.check.js");
10 const webpackOptionsSchema = require("../schemas/WebpackOptions.json");
11 const Compiler = require("./Compiler");
12 const MultiCompiler = require("./MultiCompiler");
13 const WebpackOptionsApply = require("./WebpackOptionsApply");
15 applyWebpackOptionsDefaults,
16 applyWebpackOptionsBaseDefaults
17 } = require("./config/defaults");
18 const { getNormalizedWebpackOptions } = require("./config/normalization");
19 const NodeEnvironmentPlugin = require("./node/NodeEnvironmentPlugin");
20 const memoize = require("./util/memoize");
22 /** @typedef {import("../declarations/WebpackOptions").WebpackOptions} WebpackOptions */
23 /** @typedef {import("./Compiler").WatchOptions} WatchOptions */
24 /** @typedef {import("./MultiCompiler").MultiCompilerOptions} MultiCompilerOptions */
25 /** @typedef {import("./MultiStats")} MultiStats */
26 /** @typedef {import("./Stats")} Stats */
28 const getValidateSchema = memoize(() => require("./validateSchema"));
39 * @param {ReadonlyArray<WebpackOptions>} childOptions options array
40 * @param {MultiCompilerOptions} options options
41 * @returns {MultiCompiler} a multi-compiler
43 const createMultiCompiler = (childOptions, options) => {
44 const compilers = childOptions.map(options => createCompiler(options));
45 const compiler = new MultiCompiler(compilers, options);
46 for (const childCompiler of compilers) {
47 if (childCompiler.options.dependencies) {
48 compiler.setDependencies(
50 childCompiler.options.dependencies
58 * @param {WebpackOptions} rawOptions options object
59 * @returns {Compiler} a compiler
61 const createCompiler = rawOptions => {
62 const options = getNormalizedWebpackOptions(rawOptions);
63 applyWebpackOptionsBaseDefaults(options);
64 const compiler = new Compiler(options.context, options);
65 new NodeEnvironmentPlugin({
66 infrastructureLogging: options.infrastructureLogging
68 if (Array.isArray(options.plugins)) {
69 for (const plugin of options.plugins) {
70 if (typeof plugin === "function") {
71 plugin.call(compiler, compiler);
73 plugin.apply(compiler);
77 applyWebpackOptionsDefaults(options);
78 compiler.hooks.environment.call();
79 compiler.hooks.afterEnvironment.call();
80 new WebpackOptionsApply().process(options, compiler);
81 compiler.hooks.initialize.call();
86 * @callback WebpackFunctionSingle
87 * @param {WebpackOptions} options options object
88 * @param {Callback<Stats>=} callback callback
89 * @returns {Compiler} the compiler object
93 * @callback WebpackFunctionMulti
94 * @param {ReadonlyArray<WebpackOptions> & MultiCompilerOptions} options options objects
95 * @param {Callback<MultiStats>=} callback callback
96 * @returns {MultiCompiler} the multi compiler object
99 const asArray = options =>
100 Array.isArray(options) ? Array.from(options) : [options];
102 const webpack = /** @type {WebpackFunctionSingle & WebpackFunctionMulti} */ (
104 * @param {WebpackOptions | (ReadonlyArray<WebpackOptions> & MultiCompilerOptions)} options options
105 * @param {Callback<Stats> & Callback<MultiStats>=} callback callback
106 * @returns {Compiler | MultiCompiler}
108 (options, callback) => {
109 const create = () => {
110 if (!asArray(options).every(webpackOptionsSchemaCheck)) {
111 getValidateSchema()(webpackOptionsSchema, options);
114 "webpack bug: Pre-compiled schema reports error while real schema is happy. This has performance drawbacks.",
115 "DEP_WEBPACK_PRE_COMPILED_SCHEMA_INVALID"
118 /** @type {MultiCompiler|Compiler} */
121 /** @type {WatchOptions|WatchOptions[]} */
123 if (Array.isArray(options)) {
124 /** @type {MultiCompiler} */
125 compiler = createMultiCompiler(
127 /** @type {MultiCompilerOptions} */ (options)
129 watch = options.some(options => options.watch);
130 watchOptions = options.map(options => options.watchOptions || {});
132 const webpackOptions = /** @type {WebpackOptions} */ (options);
133 /** @type {Compiler} */
134 compiler = createCompiler(webpackOptions);
135 watch = webpackOptions.watch;
136 watchOptions = webpackOptions.watchOptions || {};
138 return { compiler, watch, watchOptions };
142 const { compiler, watch, watchOptions } = create();
144 compiler.watch(watchOptions, callback);
146 compiler.run((err, stats) => {
147 compiler.close(err2 => {
148 callback(err || err2, stats);
154 process.nextTick(() => callback(err));
158 const { compiler, watch } = create();
162 "A 'callback' argument needs to be provided to the 'webpack(options, callback)' function when the 'watch' option is set. There is no way to handle the 'watch' option without a callback.",
163 "DEP_WEBPACK_WATCH_WITHOUT_CALLBACK"
171 module.exports = webpack;