webpack构建流程解析

1,784 阅读3分钟

1. 什么是webpack

webpack是一个模块化打包工具,它将一切文件都视为模块,通过loader编译转换文件,通过plugin注入钩子,最后将输出的资源模块组合成文件。

它的主要的配置信息有entryoutputmodulesplugins

2. 构建流程

基础概念

  1. CompilerWebpack的运行入口,实例化时定义webpack构建主要流程,同时创建构建时使用的核心对象compilation
  2. Compilation: 由Compiler实例化,存储构建过程中流程使用到的数据,用户控制这些数据的变化,每一次构建创建一个Compilation实例
  3. Chunk:一般一个入口对应一个Chunk
  4. Module:用于表示代码模块的类型,有很多子类用于处理不同情况的模块,模块相关信息都可以从Module实例中获取,例如dependiencies记录模块的依赖信息
  5. Parser:基于acorn来分析AST语法树,解析出代码模块的依赖
  6. Dependency:解析时用户保存代码模块对应的依赖使用的对象
  7. Template: 生成最终代码要使用到的代码模块

基本流程

  1. 创建Compiler实例,用于控制构建流程,compiler实例包含webpack基本环境信息
  2. 根据配置项转换成对应内部插件,并初始化options配置项
  3. 执行compiler.run
  4. 创建Compiltation实例,每次构建都会新创建一个Compiltation实例,包含了这次构建的基本信息
  5. entry开始递归分析依赖,对每个依赖模块进行buildModule,通过Loader将不同类型的模块转换成Webpack模块
  6. 调用Parser.parse将上面的结果转换成AST
  7. 遍历AST树,收集依赖dependency,并保存在compilation实例的dependiencies属性中
  8. 生成chunks,不同entry生成不同chunk,动态导入也会生成自己的chunk,生成chunk后还会进行优化
  9. 使用template基于compilation的数据生成结果代码

编译过程

  • 第一步: 先初始化参数,通过 yargswebpack.config.jsshell 脚本的配置信息合并,进行参数的初始化;
  • 第二步:利用初始化的参数创建complier对象,complier可以视为一个webpack的实例,存在于webpack从启动到结束的整个过程,他包含了webpackmoduleplugin等参数信息,然后调用complier.run方法开始编译。
  • 第三步:根据entry信息找到入口文件,创建compilation对象,可以理解为webpack一次编译的过程,包含了当前编译环境的所有资源,包括编译后的文件。
  • 第四步:通过配置信息,调用loader进行模块翻译,使用acorn将模块转换为AST,当遇到require依赖时,创建依赖并加入依赖数组,再找出依赖的依赖,递归处理所有的依赖。
  • 第五步:完成第四步后将得到所有模块的依赖关系和模块翻译后的文件,然后调用 compilation.seal 方法,对这些模块和根据模块依赖关系创建的chunk进行整理,将所有资源进行合并拆分等操作。这是最后一次能修改输出内容的地方。
  • 第六步:根据配置信息中的output配置,进行最后模块的文件输出,指定输出文件名和文件路径。

3. 原理

webpack打包输出后的文件其实就是一个闭包,传入的参数是一个对象,键值为所有输出文件的路径,内容为eval包裹的文件内容;闭包内重写了模块的加载方式,自己定义了__webpack_require__方法,来实现模拟的commonjs规范模块加载机制。

webpack实际上是基于事件流的,通过一系列的插件来运行。webpack利用tapable库提供各种钩子来实现对于整个构建流程各个步骤的控制。