目前本文介绍的是webpack的打包原理,还会有涉及到的

  1. webpack 构建流程(编译原理?)是怎样的?(本文)
  2. webpack loader 和 plugin 的原理和区别?(更新中)
  3. plugin 中有异步请求会阻塞后面的 plugin 吗?
  4. webpack 热更新原理?
  5. 你webpack 是怎么做拆包(分包)的?
  6. 做过webpack 性能优化吗?

webpack是高度复杂抽象的插件集合,理解webpack的运行机制,对于我们日常定位构建错误以及写一些插件处理构建任务有很大的帮助。
webpack 的作用是根据入口文件将源代码编译(构建、打包)成最终代码。中间经过webpack打包,打包的过程就是编译

核心打包原理

主要流程

初始化 -> 编译 -> 输出

  • 初始化这个阶段,webpack会将CLI参数、配置文件、默认配置进行融合,形成一个最终的配置对象
  • 编译阶段,1.创建chunk 2.构建所有依赖模块 3.产生 chunk assets 4.合并 chunk assets,
  • 输出阶段,利用node模块里的fs模块,根据编译产生总的asset以及结合output输出文件

具体webpack细节

  • 获取主模块内容
  • 分析模块
    安装@babel/parser包(转AST)
  • 对模块内容进行处理
    安装@babel/traverse包(遍历AST收集依赖)
    安装@babel/core和@babel/preset-env包(es6转ES5)
  • 递归所有模块生成最终代码

重要的构建节点

webpack的构建中总会经历如下几个事件节点。
before-run 清除缓存
run 注册缓存数据钩子
compile 开始编译
make 从入口分析依赖以及间接依赖模块,创建模块对象
build-module 模块构建
seal 构建结果封装, 不可再更改
after-compile 完成构建,缓存数据
emit 输出到dist目录

其中make是整个构建中最核心的部分编译,通过模块工厂函数创建模块,然后对模块进行编译。

在make钩子的编译

构建封装seal

到构建封装阶段时候,代码构建已经完毕,但是如何将这些代码按照依赖引用逻辑组织起来,当浏览器将你构建出来的代码加载到浏览器的时候,仍然能够正确执行。在webpack中通过Manifest记录各个模块的详细要点,通过Runtime来引导,加载执行模块代码,特别是异步加载。

参考文件