插件不是“配一下就能用”,它是一段在构建流程的特定时间点执行的代码。
写过 Webpack 插件的人,大概都见过这段模板代码:

这段代码能跑,但你有没有想过:compiler是什么?compilation是什么?emit这个钩子为什么能拿到产物?如果我想在模块解析阶段动手,该用哪个钩子?
今天从 Compiler、Compilation、以及一条完整构建时间线三个角度,拆解 Rspack / Webpack 插件机制。理解了这些钩子,你才知道“在哪个阶段做什么事”。
一、Compiler 和 Compilation:两个核心对象
Compiler 是整个构建流程的“总控”。它包含了完整的 Webpack / Rspack 环境配置,从启动到结束,全程只有一个 Compiler 实例。它负责触发全局级别的生命周期事件:beforeRun、run、watchRun、done、failed 等。
Compilation 是每次构建的“现场”。每次重新编译(比如文件变更触发的增量构建)都会生成一个新的 Compilation 实例,负责当前这次构建的所有细节:模块解析、依赖收集、优化、分块、产物生成。
两者的关系可以这样理解:Compiler 是“工厂”,Compilation 是“产品线”。Compiler 启动一次,可能触发多次 Compilation(比如 watch 模式下文件变了就重新跑一次构建)。
二、构建时间线:钩子在什么时机触发?
一条典型的构建流程,钩子的触发顺序大致如下:
启动阶段:
beforeRun、run(非 watch 模式)或 watchRun(watch 模式)。beforeRun 适合做构建前的准备工作,比如清理临时目录。watchRun 可以通过compiler.modifiedFiles 拿到变更的文件列表。
编译阶段:
beforeCompile → compile → thisCompilation / compilation → make → finishMake → afterCompile。make 阶段是构建模块依赖图的核心——以 entry 为起点,递归解析所有依赖,用 loader 处理每个模块。
产出阶段:
shouldEmit → emit → afterEmit → done。emit 钩子是在产物写入磁盘之前触发的,这是修改产物的最后机会。
注意:beforeRun 和run 只在命令行build 时触发,watch 模式用 watchRun 替代。
三、几个关键钩子的用途
compilation 和thisCompilation
这两个钩子都在 Compilation 创建时触发,区别在于:thisCompilation 不会被复制到 child compiler,compilation 会被复制。如果你写的插件只关心主构建流程,用thisCompilation 就够了;如果插件需要和子编译器(比如 worker 或 child 构建)交互,用 compilation。
用法示例(Rspack 官方):

拿到compilation之后,你可以在模块构建、优化、产物生成等更细粒度的节点上做操作。
processAssets
Rspack 和 Webpack 5 推荐用processAssets 替代直接在emit 里操作 compilation.assets。它有明确的 stage 参数,可以控制插件在哪个阶段处理产物:PROCESS_ASSETS_STAGE_OPTIMIZE 做优化,PROCESS_ASSETS_STAGE_ADDITIONS 加内容,PROCESS_ASSETS_STAGE_OPTIMIZE_SIZE 压缩。

make 和afterCompile
make 是构建模块依赖图的核心阶段,如果你需要干预模块解析过程,这是最合适的时机。afterCompile 在模块构建完成、进入 seal(封存)阶段之前触发,适合做模块级别的收尾处理。
四、Rspack 的特殊之处
Rspack 的核心编译逻辑跑在 Rust 侧,因此大部分 Compilation 钩子在 JavaScript 侧是只读的。对 JavaScript 侧的修改不会同步到 Rust 侧。这意味着某些在 Webpack 里惯用的操作方式,在 Rspack 里可能不生效。
建议:优先使用 Rspack 官方文档里标记了可用的钩子和操作方式,比如processAssets这类通过官方 API 操作产物的方式。
最后
理解 Compiler 和 Compilation 的生命周期,是写插件的基本功。知道钩子在什么时候触发、能拿到什么数据,你才能精准地“插入”到构建流程里——而不是靠试错。
下次写插件,先问自己:我要干预的是“全局流程”还是“单次构建”?这个操作应该发生在模块解析阶段、优化阶段、还是产物生成阶段?答案会告诉你该用哪个钩子。
如果这篇文章对你有帮助,欢迎点赞、在看、转发。
夜雨聆风