⚡ 30 秒速记
- 先串入口:参数归一化 → 创建
Compiler→ 注册插件 → 开始构建 Compiler管整体生命周期,Compilation管一次编译- 钩子让解析、优化、输出阶段可以被扩展
- 看模块如何进入依赖图,再看
seal如何整理产物 - 源码结论标明
webpack 4,内部结构会随版本变化
读打包器源码,先抓住一次构建怎么被推动,比逐行看每个函数更有效。 Compiler 像构建任务的总调度,Compilation 保存本轮模块、代码块和资源。插件通过钩子加入不同阶段,模块工厂负责创建模块并继续发现依赖。沿着入口到模块构建,再到代码块优化和文件输出走一遍,遇到具体问题时就能找到对应环节,而不是只记住一串类名。
版本校准: 旧文中的 webpack 4、JSONP 更新清单或 react-hot-loader 代码用于解释历史链路,不应直接复制到新项目。当前 webpack-dev-server 4+ 默认启用 HMR,严格 ESM 可使用 import.meta.webpackHot;生产环境不得携带 HMR runtime。以 webpack HMR 官方指南 和项目锁定版本为准。
# Webpack本质
Webpack本质上一种基于事件流的编程范例,其实就是一系列的插件运行
Webpack主要使用Compiler和Compilation两个类来控制Webpack的整个生命周期。他们都继承了Tapabel并且通过Tapabel来注册了生命周期中的每一个流程需要触发的事件
# Tapabel
Tapabel是一个类似于Node.js的EventEmitter的库,主要是控制钩子函数的发布与订阅,是Webpack插件系统的大管家
Tapabel提供的钩子及示例
Tapable库为插件提供了很多 Hook以便挂载。
const {
SyncHook, // 同步钩子
SyncBailHook, // 同步熔断钩子
SyncWaterfallHook, // 同步流水钩子
SyncLoopHook, // 同步循环钩子
AsyncParalleHook, // 异步并发钩子
AsyncParallelBailHook, // 异步并发熔断钩子
AsyncSeriesHook, // 异步串行钩子
AsyncSeriesBailHook, // 异步串行熔断钩子
AsyncSeriesWaterfallHook // 异步串行流水钩子
} = require("tapable");
Tabpack提供了同步&异步绑定钩子的方法,方法如下所示:
| Async | Sync |
|---|---|
绑定:tapAsync/tapPromise/tap |
绑定:tap |
执行:callAsync/promise |
执行:call| |
Tabpack简单示例
const demohook = new SyncHook(["arg1", "arg2", "arg3"]);
// 绑定事件到webpack事件流
demohook.tap("hook1",(arg1, arg2, arg3) => console.log(arg1, arg2, arg3)) // 1 2 3
// 执行绑定的事件
demohook.call(1,2,3)