webpack 原理之编译前流程全解析

一、Webpack 初始化:命令入口的选择

当在终端输入 webpack 命令,流程从 Webpack 初始化环节开启,核心文件为 webpack/bin/webpack.js 。此阶段首要任务是判断 webpack-cli 的安装情况:

  • 检测与分支逻辑 :代码会先检查系统是否安装 webpack-cli 。若未安装,会进入安装命令判断流程,识别是 yarnpnpm 还是 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 方法:

  1. 参数解析run 方法首要工作是解析命令行参数,借助 Commander.js 库,识别 --mode--config 等选项,明确用户执行命令的意图 。
js 复制代码
const { program } = require("commander");​
// 注册命令执行逻辑​
program.action(async (options, cmd) => {​
// 处理参数并启动后续流程​
await loadCommand(cmd, options);​
});​

// 解析命令行参数​
program.parse(process.argv);
  1. 回调与子命令 :通过 this.program.action() 定义回调,触发 parseAsync 解析参数。之后创建子命令,先调用 loadCommandByName 按名称查找对应命令,再用 makeCommand 创建子命令并添加回调。
  2. 触发与执行 :完成子命令配置后,再次触发 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 巧妙处理了环境检测、命令解析、编译器初始化等环节,既保证了不同环境(本地 / 全局 )的兼容性,又为编译过程做好充足准备。

相关推荐
naice31 分钟前
我对github的图片很不爽了,于是用AI写了一个图片预览插件
前端·javascript·git
天蓝色的鱼鱼35 分钟前
Element UI 2.X 主题定制完整指南:解决官方工具失效的实战方案
前端·vue.js
RoyLin40 分钟前
TypeScript设计模式:门面模式
前端·后端·typescript
小奋斗43 分钟前
千量数据级别的数据统计分析渲染
前端·javascript
小文刀6961 小时前
CSS-响应式布局
前端
三小河1 小时前
overflow:auto 滚动的问题,以及flex 布局中如何设置
前端·javascript
薛定谔的算法1 小时前
phoneGPT:构建专业领域的检索增强型智能问答系统
前端·数据库·后端
Hilaku1 小时前
Token已过期,我是如何实现无感刷新Token的?
前端·javascript·面试
小文刀6961 小时前
2025-35st-w-日常开发总结
前端
我是日安1 小时前
从零到一打造 Vue3 响应式系统 Day 8 - Effect:深入剖析嵌套 effect
前端·vue.js