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

相关推荐
带只拖鞋去流浪1 分钟前
迎接2026,重新认识Vue CLI (v5.x)
前端·vue.js·webpack
c***V3233 小时前
Vue优化
前端·javascript·vue.js
李@十一₂⁰5 小时前
HTML 特殊字体符号
前端·html
小奶包他干奶奶7 小时前
Webpack学习——Loader(文件转换器)
前端·学习·webpack
小奶包他干奶奶7 小时前
Webpack学习——原理理解
学习·webpack·devops
zy happy7 小时前
若依 vue3 报错:找不到模块“@/api/xxxx/xxxxx”或其相应的类型声明。。Vue 3 can not find mod
前端·javascript·vue.js
潘小安8 小时前
Git Worktree + Claude Code:让你的开发效率翻倍的秘密武器
前端
meichaoWen8 小时前
【Vue3】vue3的全面学习(一)
前端·javascript·学习
小猪努力学前端8 小时前
在 React + React Router v7 SSR 项目里做多端适配,我踩的两个坑
前端·react.js
q***d1739 小时前
React桌面应用开发
前端·react.js·前端框架