webpack 编译过程大致分为三个步骤
- 初始化
- 编译
- 输出
(一)初始化
此阶段,webpack 会将CLI 参数、配置文件、默认配置进行融合,形成一个最终的配置对象
(二)编译
index.js
console.log("index");
require("./a");
a.js
require("./b");
console.log("a");
module.exports = "a";
b.js
console.log("b");
module.exports = "b";
1. 创建 chunk
chunk 是 webpack 在内部构建过程中的一个概念,译为块,
它就是一个入口,通过这个入口可以找到所有依赖
根据入口模块(默认为 ./src/index.js
)创建一个 chunk
每个 chunk 都有至少两个属性:
- name:默认为 main
- id:唯一编号,开发环境和 name 相同,生产环境是一个数字,从 0 开始
2. 构建所有依赖模块
- 模块文件:首先拿到的是一个入口模块,根据入口模块开始构建
-
检查记录:webpack 维护了一张表格,表格里面记录了所有已经加载的模块,这个过程就是检查当前的模块有没有加载过
- 如果加载过,就结束
- 如果没有加载过,就在表格里面记录下,然后继续编译过程
- 读取文件内容
- 进行语法分析:通过将代码转换成一个 AST 抽象语法树进行分析,通过遍历 AST 抽象语法树找到当前模块的依赖
-
记录依赖:把依赖记录到一个叫做 dependencies 的数组里面
- 比如记录 index.js 的依赖:["./src/a.js"]
-
替换依赖函数:就是把
require
改成__webpack_require
- 可以参考我的另一篇笔记https://www.jianshu.com/p/c7e5ed093159
- 举个例子,替换完成之后 index.js 变成
console.log("index");
__webpack_require("./src/a.js");
-
保存转换后的模块代码
- 根据 dependencies 数组里面的内容递归加载模块
以上做的所有事情其实就是为了生成那张记录模块id 和 转换后的代码的表
3. 产生 chunk assets
在第二步完成后,chunk 中会产生一个模块列表,列表中包含了模块 id 和模块转换后的代码
接下来,webpack 会根据配置为 chunk 生成一个资源列表,即 chunk assects,资源列表可以理解为是生成到最终文件的文件名和文件内容
举个例子
文件名:"./dist/main.js"
(function(modules){
})({
"./src/index.js": xxxxxxx
})
参考:https://www.jianshu.com/p/c7e5ed093159
用一个简图表示:
4. 合并 chunk assets
有的时候入口文件有多个,这个时候就会编译出多个 chunk,这个步骤就是将多个 chunk 的 assets 合并到一起,并产生一个总的 hash
(三)输出
就是 webpack 利用 node 中的 fs 模块(文件处理模块),根据编译产生的总的 assets,根据 assets 数组里面的文件名,文件内容,生成相应的文件
总结一下:
一些术语
- module:模块,分割的代码单元,webpack 中的模块可以是一个图片,css,不限于 JS,可以看成是 webpack 处理文件的单位
- chunk:webpack 内部构件模块,的,块,一个 chunk 中包含多个模块,这些模块是从入口模块通过依赖分析得来的
- bundle:就是最终要生成的文件
- hash:最终所有内容生成的那个 assets 所有应的 hash
- chunkhash:chunk 生成的 assets 所对应的 hash
- chunkname:chunk 的名称,如果没有配置则使用 main
- id:通常指 chunk 的唯一编号,在开发环境下与 chunkname 相同;如果是生产环境,则使用一个从 0 开始的数字进行编号
网友评论