一、Webpack 初始化:命令入口的选择
当在终端输入 webpack
命令,流程从 Webpack 初始化环节开启,核心文件为 webpack/bin/webpack.js
。此阶段首要任务是判断 webpack-cli
的安装情况:
- 检测与分支逻辑 :代码会先检查系统是否安装
webpack-cli
。若未安装,会进入安装命令判断流程,识别是yarn
、pnpm
还是npm
包管理器,接着询问用户是否安装(y/n
交互 )。若用户输入n
,流程直接终止;输入y
,则加载可执行路径webpack-cli/bin/cli.js
继续执行 。 - 本地与全局的选择 :若已安装
webpack-cli
,会进一步判断是使用项目本地的webpack-cli
还是全局版本。优先检测本地是否有可用实例,存在则走本地逻辑,确保项目依赖环境的一致性;若本地无,才使用全局逻辑,避免因版本差异引发问题。
二、webpack-cli 流程:命令解析与实例化
进入 webpack-cli/lib/webpack-cli.js
后,runCLI
函数登场,它会新建 WebpackCLI
实例并执行 run
方法:
- 参数解析 :
run
方法首要工作是解析命令行参数,借助 Commander.js 库,识别--mode
、--config
等选项,明确用户执行命令的意图 。
js
const { program } = require("commander");
// 注册命令执行逻辑
program.action(async (options, cmd) => {
// 处理参数并启动后续流程
await loadCommand(cmd, options);
});
// 解析命令行参数
program.parse(process.argv);
- 回调与子命令 :通过
this.program.action()
定义回调,触发parseAsync
解析参数。之后创建子命令,先调用loadCommandByName
按名称查找对应命令,再用makeCommand
创建子命令并添加回调。 - 触发与执行 :完成子命令配置后,再次触发
parseAsync
,随后运行runWebpack
方法,为编译器创建做准备。
js
//加载webpack 定位webpack/package.json的main指向的文件(webpack/lib/index->webpack/lib/webpack.js)
async loadWebpack(handleError = true) {
return this.tryRequireThenImport(WEBPACK_PACKAGE, handleError);
}
async run(args, parseOptions) {
this.webpack = await this.loadWebpack();
async createCompiler(options, callback) {
let compiler;
try {
compiler = this.webpack(config.options, callback
? (error, stats) => {}
callback(error, stats);
}
: callback);
}
catch (error) {}
return compiler;
}
}
async runWebpack(options, isWatchCommand) {
let compiler;
compiler = await this.createCompiler(options, callback);
if (!compiler) {
return;
}
}
三、编译器创建
在 webpack-cli
流程末尾,会调用 createCompiler
方法,衔接至 webpack/lib/webpack.js
:
- 实例化编译器 :
createCompiler
内部通过new Compiler()
创建编译器实例,同时整合配置信息,包括从命令行参数、配置文件(如webpack.config.js
)中获取的内容,初始化编译器的基础环境 。 - 为编译准备 :编译器创建完成后,并非立刻开始编译,而是做好各项准备,比如加载插件(默认插件和用户自定义插件 )、初始化编译所需的钩子等,等待
compiler.run
方法调用,正式开启编译流程。
js
const createCompiler = (rawOptions, compilerIndex) => {
//创建编译器
const compiler = new Compiler(
/** @type {string} */ (options.context),
options
);
//启用各种插件
new NodeEnvironmentPlugin({
infrastructureLogging: options.infrastructureLogging
}).apply(compiler);
if (Array.isArray(options.plugins)) {
} else if (plugin) {
plugin.apply(compiler);
}
}
}
//调用钩子
compiler.hooks.environment.call();
compiler.hooks.afterEnvironment.call();
new WebpackOptionsApply().process(options, compiler);
compiler.hooks.initialize.call();
return compiler;
};
四、总结
从终端输入 webpack
命令,到编译器创建完毕,完整流程可概括为:

这一过程中,Webpack 巧妙处理了环境检测、命令解析、编译器初始化等环节,既保证了不同环境(本地 / 全局 )的兼容性,又为编译过程做好充足准备。