1 主要事件结点

Webpack 主要的事件结点如下:

  • entry-option 初始化option
  • run
  • make 从 entry 分析模块及其依赖的模块,对每个依赖模块进行 build
  • before-resolve 对模块位置进行解析
  • build-module 构建模块
  • normal-module-loader 将 loader 加载完成的 module 进行编译,生成 AST 树
  • program 遍历 AST,收集依赖
  • seal 所有依赖 build 完成,进行优化
  • emit 把各个 chunk 输出到结果文件

2 实现细节

2.1 编译与构建主流程

  1. 初始化阶段:根据配置初始化插件
  2. 通过 entry 找到入口文件,然后:
    • 调用各个 loader 处理模块之间的依赖:比如 url-loader、jsx-loader、css-loader 等等来让我们可以直接在源文件中引用各类资源。… 最后生成一个 js module。
    • 调用 acron 解析经 loader 处理后的源文件生成抽象语法树
    • 遍历 AST,构建该模块所依赖的模块:将 require 中的模块添加到依赖中,递归前面的步骤。
  3. 输出文件资源

    2.2 Compilation

  • compiler 调用 compilation 的生命周期方法
  • EntryPlugin 调用 compilation.addEntry 添加入口
  • NormalModuleFactory
  • compilation.factorizeQueue 调用 compilation._factorizeModule
  • compilation.handleModuleCreation
  • compilation.addModule
  • compilation.buildModule
  • NormalModule.build
  • 把 modules 存放到 compilation 对象上

    2.3 Module

    可以理解为一个JS文件对应一个module, 可以分为:

  • NormalModule

  • ContextModule: ./src/a
  • ExternalModule: module.exports = jQuery
  • DelegatedModule
  • MultiModule

    2.3.1 NormalModule

  • doBuild

  • loader-runner::runLoaders
  • 调用 parser.parse 分析 ast

    2.4 Chunk

    chunk 生成算法:

  • 从 entry 开始创建新的 chunk

  • 将依赖的 module 添加到 chunk 里面
  • 如果遇到动态 import,创建新的 chunk
  • 重复上面步骤直到结束

参考