前端工程化 - 依赖图的构建
依赖图的构建
本质:
我理解构建工具的依赖图构建能力,它本质上是:
能否准确的分析模块之间的依赖关系,并基于这张依赖图,支撑构建,拆包,缓存,和增量更新等一系列工程能力
到底是什么?
在构建过程中,构建工具会把每一个模块当成一个节点,把
import/require当成边,最终形成一张有向的依赖图,从入口文件向下展开
构建工具强不强,核心不在API,而在这张依赖图是不是完整,准确,可维护的.
依赖图强不强, 决定了哪些能力?
tree shaking, 代码拆包, HMR, 增量构建,本质上都是依赖于这张依赖图
例子
以tree shaking为例, 它的前提是
构建工具必须知道哪些模块被谁依赖,哪些导出实际被使用
// utils.ts
export function a(){}
export function b() {}
export function c() {}
// page.ts
import { a } from './utils'
如果依赖图是精确的, 构建工具就能明确知道, b和 c没有任何入边, 在生产构建中可以被安全移除
但如果模块边界不清晰,或存在副作用, 构建工具在依赖图层面就无法确认安全性, tree shaking就会失效
为什么 vite 的 dev 启动快?
vite 在开发阶段快, 本质原因不是它更快. 而是它不需要一开始就构建完整的依赖图
webpack:
- 启动时,从入口开始
- 递归解析整张依赖图
- 打包成bundle
vite:
- 启动时只处理入口和HTML
- 依赖图是按浏览器请求逐步补全的
webpack 是把整张依赖图算完再跑
vite 是边跑边补充依赖图
HMR / 增量构建为什么离不开依赖图?
在HMR或增量构建中, 构建工具需要快速判断: 一个模块的改动,会影响哪些模块?
如:
App
├─ PageA
│ └─ Chart
└─ PageB
如果我只改了
chat, 构建工具通过依赖图就能准确判断,只需要更新 PageA 这一条路径,而不需要重新构建整个应用.
依赖图越精确, HMR的更新范围就越小,开发体验就越好
工程方面
所以我看一个构建工具,不会只看配置是否简单.
而是看他在复杂工程下,依赖图是否稳定, 是否可预测, 是否能支撑长期演进

浙公网安备 33010602011771号