Skip to content

编译过程

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

image-20220627164436495

整个过程大致分为三个步骤:

  1. 初始化
  2. 编译
  3. 输出

初始化

此阶段,webpack 会将 cli 参数配置文件默认配置进行融合,形成一个最终的配置对象。对配置的处理过程是依托一个第三方库yargs完成的。

此阶段相对比较简单,主要是为接下来的编译阶段做必要的准备,我们可以简单的理解为,初始化阶段主要目的是产生一个最终的配置。

编译

1. 创建 chunk

chunk 是 webpack 在内部构建模块过程中的一个概念,译为,它表示通过某个入口找到的所有依赖的统称。

根据入口模块(默认为./src/index.js)创建一个 chunk。

image-20220627164401087

每个 chunk 都有至少两个属性:

  • name:默认为 main
  • id:唯一编号,开发环境和 name 相同,生产环境是一个数字,从 0 开始

2. 构建所有依赖模块

image-20220627165922462

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

3. 生成 chunk assets

在第二步完成后,chunk 中会产生一个模块列表,列表中包含了模块 id模块转换后的代码

接下来,webpack 会根据配置为 chunk 生成一个资源列表,即chunk assets,资源列表中的每一项称为 bundle,可以理解为是生成到最终文件夹的文件名和文件内容。

image-20220706095227576

chunk hash 是根据 chunk assets 的所有内容生成的一个 hash 字符串。

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

4. 合并 chunk assets

将所有 chunk 的 chunk assets 合并到一起,并产生一个总的 hash。

image-20220706095743877

输出

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

image-20220706095943423

总结

webpack 的编译过程

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

image-20220706101608450

webpack是如何通过入口文件找到所有依赖的?

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

image-20220627165922462