// 源码 121 ~ 193 行
const webpack = /** @type {WebpackFunctionSingle & WebpackFunctionMulti} */ (
/**
* @param {WebpackOptions | (ReadonlyArray<WebpackOptions> & MultiCompilerOptions)} options options
* @param {Callback<Stats> & Callback<MultiStats>=} callback callback
* @returns {Compiler | MultiCompiler | null} Compiler or MultiCompiler
*/
(options, callback) => {
const create = () => {
if (!asArray(options).every(webpackOptionsSchemaCheck)) {
getValidateSchema()(webpackOptionsSchema, options);
util.deprecate(
() => {},
"webpack bug: Pre-compiled schema reports error while real schema is happy. This has performance drawbacks.",
"DEP_WEBPACK_PRE_COMPILED_SCHEMA_INVALID"
)();
}
/** @type {MultiCompiler|Compiler} */
let compiler;
/** @type {boolean | undefined} */
let watch = false;
/** @type {WatchOptions|WatchOptions[]} */
let watchOptions;
if (Array.isArray(options)) {
/** @type {MultiCompiler} */
compiler = createMultiCompiler(
options,
/** @type {MultiCompilerOptions} */ (options)
);
watch = options.some(options => options.watch);
watchOptions = options.map(options => options.watchOptions || {});
} else {
const webpackOptions = /** @type {WebpackOptions} */ (options);
/** @type {Compiler} */
compiler = createCompiler(webpackOptions);
watch = webpackOptions.watch;
watchOptions = webpackOptions.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,
/** @type {options extends WebpackOptions ? Stats : MultiStats} */
(stats)
);
});
});
}
return compiler;
} catch (err) {
process.nextTick(() => callback(/** @type {Error} */ (err)));
return null;
}
} else {
const { compiler, watch } = create();
if (watch) {
util.deprecate(
() => {},
"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.",
"DEP_WEBPACK_WATCH_WITHOUT_CALLBACK"
)();
}
return compiler;
}
}
);
webpack 函数可以根据传入的配置选项创建 Webpack 编译器实例,并根据配置决定是否启动监听模式。
主要功能和逻辑
-
参数处理:
- 函数接受两个参数:
options
和callback
。 options
可以是单个 Webpack 配置对象或一个 Webpack 配置对象数组。callback
是一个可选的回调函数,用于处理编译结果。
- 函数接受两个参数:
-
配置验证:
- 使用
webpackOptionsSchemaCheck
函数验证传入的配置是否符合预期。 - 如果配置不符合预期,使用
getValidateSchema()
函数进行详细验证,并输出警告信息。
- 使用
-
编译器创建:
- 根据
options
的类型(单个配置或多个配置),调用createCompiler
或createMultiCompiler
函数创建相应的编译器实例。 - 处理
watch
选项,确定是否需要监听文件变化。
- 根据
-
编译执行:
- 如果提供了
callback
,根据watch
选项决定是启动监听模式还是执行一次编译。 - 在监听模式下,调用
compiler.watch
方法。 - 在非监听模式下,调用
compiler.run
方法执行编译,并在编译完成后关闭编译器。 - 如果编译过程中发生错误,通过
callback
返回错误信息。
- 如果提供了
-
无回调情况处理:
- 如果未提供
callback
且设置了watch
选项,输出警告信息,提示需要提供回调函数以处理监听模式。
- 如果未提供
-
错误处理:
- 在编译过程中捕获任何异常,并通过
process.nextTick
调用callback
返回错误信息
- 在编译过程中捕获任何异常,并通过
这段代码实现了 Webpack 的核心功能,包括配置验证、编译器创建、编译执行以及错误处理。