上篇写了webpack编译结果分析,这一篇讲一下webpack的编译过程。
众所周知,webpack 的作用是将源代码编译(构建、打包)成最终代码。整个过程可以概括为三个步骤:初始化、编译、输出。
初始化
此阶段,webpack会将CLI参数、配置文件、默认配置进行融合,形成一个最终的配置对象。
对配置的处理过程是依托一个第三方库yargs
完成的
此阶段相对比较简单,主要是为接下来的编译阶段做必要的准备。可以简单地理解为,初始化阶段主要用于产生一个最终的配置
编译
以下面简单的模块为示例:
1. 创建chunk
chunk是webpack在内部构建过程中的一个概念,译为块,它表示通过某个入口找到的所有依赖的统称。(从入口开始分析的整个依赖关系)
根据入口模块创建一个chunk
每个chunk都有至少两个属性:
-
name:默认为main
-
id:唯一编号,开发环境和name相同,生产环境是一个数字,从0开始
2. 构建所有依赖模块
关于根据dependencies的内容递归加载模块:
这一步完成后,在chunk里会形成多个模块。这些模块是由入口模块一个个加载出来的,每个模块记录了模块转换后的代码。
3. 产生chunk assets
在第二步完成后,chunk中会产生一个模块列表,列表中包含了模块id和模块转换后的代码
接下来,webpack会根据配置为chunk生成一个资源列表,即chunk assets
,资源列表可以理解为是生成到最终文件的文件名和文件内容
注:如图中的./dist/main.js.map,一个chunk可能生成多个文件
chunk hash是根据所有chunk assets的内容生成的一个hash字符串
hash:一种算法,具体有很多分类,特点是将一个任意长度的字符串转换为一个固定长度的字符串,而且可以保证原始内容不变,产生的hash字符串就不变 不同的文件内容使用不同的hash值
./dist/main.js 文件内容示例 ([具体可参考上一篇](Webpack——编译结果简化分析 - 掘金 (juejin.cn)))
// chunk assets —— ./dist/main.js 文件内容示例
(function(modules){
})({
"./src/a.js": (function(module, exports, __webpack_require__) {
__webpack_require__(/*! ./b */ "./src/b.js")
console.log("a")
module.exports = "a"
}),
"./src/b.js": (function(module, exports) {
console.log("b")
module.exports = "b";
}),
"./src/index.js": (function(module, exports, __webpack_require__) {
console.log("index")
__webpack_require__(/*! ./a */ "./src/a.js");
__webpack_require__(/*! ./b */ "./src/b.js")
})
})
简图:
注:bundle: 捆。每个资源可以认为是一个bundle
4. 合并chunk assets
将多个chunk的assets合并到一起,并产生一个总的hash
(当前示例只有一个main chunk,还可能有多个chunk)
输出
此步骤非常简单,webpack将利用node中的fs模块(文件处理模块),根据编译产生的总的assets,生成相应的文件。
总过程
注:如果开启了watch,文件发生变化时会从编译开始重新走过程,不需要再次初始化