编译过程
webpack 的作用就是将源代码编译(构建、打包)成最终代码。

整个过程大致分为三个步骤:
- 初始化
- 编译
- 输出
初始化
此阶段,webpack 会将 cli 参数、配置文件、默认配置进行融合,形成一个最终的配置对象。对配置的处理过程是依托一个第三方库yargs完成的。
此阶段相对比较简单,主要是为接下来的编译阶段做必要的准备,我们可以简单的理解为,初始化阶段主要目的是产生一个最终的配置。
编译
1. 创建 chunk
chunk 是 webpack 在内部构建模块过程中的一个概念,译为块,它表示通过某个入口找到的所有依赖的统称。
根据入口模块(默认为./src/index.js)创建一个 chunk。

每个 chunk 都有至少两个属性:
- name:默认为 main
- id:唯一编号,开发环境和 name 相同,生产环境是一个数字,从 0 开始
2. 构建所有依赖模块

- 从入口模块开始进行构建,根据入口模块的路径找到对应的模块文件
- 检查文件加载记录
- 如果模块文件已经加载过,继续下一步骤
- 如果模块文件未加载,则加载文件,加载完毕后,继续下一步骤
- 读取模块文件的内容,对其进行语法分析,将其转换成 AST 抽象语法树
- 遍历 AST,将模块文件的所有依赖记录到 dependencies 中
- 将读取到的文件内容中的依赖函数替换成
__webpack_require(注意!这里不是修改文件内容本身,而是修改读取到的文件内容,本质是一个字符串),我们称这个字符串为转换后的模块代码 - 将转换后的模块代码保存,按照模块 id 一一映射
- 根据 dependencies 中的内容递归加载模块(回到第二步)
3. 生成 chunk assets
在第二步完成后,chunk 中会产生一个模块列表,列表中包含了模块 id 和模块转换后的代码。
接下来,webpack 会根据配置为 chunk 生成一个资源列表,即chunk assets,资源列表中的每一项称为 bundle,可以理解为是生成到最终文件夹的文件名和文件内容。

chunk hash 是根据 chunk assets 的所有内容生成的一个 hash 字符串。
hash:一种算法,具体有很多分类,特点是将一个任意长度的字符串转换为一个固定长度的字符串,而且可以保证原始内容不变,产生的 hash 字符串就不变。因此 hash 能够反映一个文件的内容是否发生了变化。
4. 合并 chunk assets
将所有 chunk 的 chunk assets 合并到一起,并产生一个总的 hash。

输出
此步骤非常简单,webpack 将利用 node 中的 fs 模块(文件处理模块),根据编译产生的总的 assets,生成相应的文件。

总结
webpack 的编译过程
- 在命令行中执行 webpack 命令
- webpack开始读取命令参数,导入配置文件,与默认配置合并为最终配置
- 根据最终的配置进行编译,一个入口代表了一个 chunk,通过入口文件找到这个 chunk 依赖的所有文件,然后生成对应的资源列表(chunk assets),然后把所有 chunk 的资源列表合并成一个完整的资源列表并生成一个总 hash
- 每个 chunk 都有自己的 id、name、chunkhash
- 最后根据完整的资源列表生成对应的文件

webpack是如何通过入口文件找到所有依赖的?
- 根据入口配置找到入口文件
- 检查文件加载记录
- 如果模块文件已经加载过,继续下一步骤
- 如果模块文件未加载,则加载文件,加载完毕后,继续下一步骤
- 读取模块文件的内容,对其进行语法分析,将其转换成 AST 抽象语法树
- 遍历 AST,将模块文件的所有依赖记录到 dependencies 中
- 将读取到的文件内容中的依赖函数替换成
__webpack_require(注意!这里不是修改文件内容本身,而是修改读取到的文件内容,本质是一个字符串),我们称这个字符串为转换后的模块代码 - 将转换后的模块代码保存,按照模块id一一映射
- 根据 dependencies 中的内容递归加载模块(回到第二步)
