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

一、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 方法:

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

相关推荐
康小汪3 小时前
AI 写 Vue 总写成同一个味道:给它装 Skills,装的不是知识是边界
前端·vue.js·人工智能·ai编程·最佳实践
智能运维指南4 小时前
研制过程“两张皮“怎么破:研制一体化支撑平台的定位、能力边界与落地前提
java·前端·人工智能·嘉为蓝鲸
白山编程大哥5 小时前
Java 后端如何优雅地把 List 集合返回给前端
java·前端·list
Flynt6 小时前
我把热榜那篇"禁用 axios"逐条实测了一遍:结论大体对,坑在它没讲的地方
前端·javascript·axios
Csvn7 小时前
bundle优化
前端
北冥有鱼7 小时前
发版后动态路由点击报 `Failed to fetch dynamically imported module`」问题上的完整排查与修复过程
前端·vue.js
静默回滚7 小时前
视频压到 25 MB 以内,码率要算、音轨要扣、余量要留
前端
用户37203749260187 小时前
把 10MB 中文语义模型塞进浏览器:STSB 做到教师模型的 93%,但线上 top1 只有 42%
前端
光锥智能8 小时前
海康机器人举行2026移动机器人新品发布会:箱式存拣升级,「明智」系列发布
java·前端·机器人
计算机魔术师8 小时前
Anthropic 上市文件最吓人的一幕,不是亏损 807 亿
前端