← 返回目录

第 10 卷

第 10 / 26 卷日期:

加载全量资源。

用户状态保留保留页面当前状态(如表单输完全丢失页面状态:刷新后页
入内容、组件状态、路由参数面回到初始状态,需重新操作
等),仅替换变化模块的逻(如重新填写表单、重新导
辑。航)。
实现原理基于 WebSocket 通信,通过浏览器刷新机制(如 F5
Webpack 监听文件变化后生或开发服务器重启),重新请
成增量更新资源,客户端加载求入口 HTML 文件,触发全量
后通过 HMR 运行时替换旧模资源加载和页面渲染。

块(卸载旧模块→加载新模块 →执行更新钩子)。

适用场景开发环境(如 React/Vue 组开发环境中 HMR 不支持的场
件开发、CSS 样式调试、JS景(如修改 Webpack 配置、
逻辑迭代),需频繁修改代码修改入口文件、核心模块变更
且依赖页面状态的场景。导致 HMR 失败),或生产环

境的强制更新。

配置复杂度需额外配置(如无需额外配置,开发服务器默 devServer.hot: true 认支持,直接刷新即可。

+ HotModuleReplacementP

lugin),部分框架(React/Vue)需安装辅助库

(如 react-refreshwebpack-plugin)。

  1. 典型使用体验对比

• HMR 体验:在 React 项目中修改某个组件的样式或逻辑,页面无刷新,组件样式/逻辑实时更新,

表单中已输入的内容仍保留。

  • 全页面刷新体验:同样修改组件,页面整体刷新,表单内容清空,需重新输入才能继续调试。
  1. 关键补充:HMR 的降级机制

当 HMR 无法成功替换模块(如修改了无法热更新的核心模块、模块替换存在依赖冲突)时, Webpack 会自动降级为全页面刷新,确保开发者能看到代码变更效果,避免开发阻塞。

钩子类型),关键生命周期钩子按构建顺序可分为以下几类:

  1. 初始化阶段钩子(构建开始前的准备工作)
  • beforeInitialize:在 Compiler 实例初始化之前触发,极少使用。
  • initialize:Compiler 实例初始化完成后触发,可用于初始化插件自身的状态。

• environment:Webpack 环境准备完成后触发(如 Node.js 环境变量配置),插件可在此阶段获

取 Webpack 环境信息。

  • afterEnvironment:环境准备完成后的后续钩子,可用于补充环境相关配置。
  1. 配置处理阶段钩子(解析与合并配置)

• entryOption:在 Webpack 解析入口配置( entry)后触发,可用于修改入口配置(如动态添

加入口)。

  • afterPlugins:所有插件初始化完成并挂载到 Compiler 后触发,可用于验证插件配置。

• afterResolvers:解析器(resolver,用于查找模块路径)初始化完成后触发,可用于自定义模块

解析规则。

  1. 编译阶段钩子(构建依赖图谱的核心阶段)

• beforeRun:在 Compiler 开始执行编译前触发(仅在首次构建和 watch 模式下重新构建时触

发),可用于预热资源、清理缓存。

  • run:Compiler 开始执行编译时触发,标志着编译流程正式启动。

• watchRun:仅在 watch 模式下(文件变化触发重新构建)触发,在编译开始前执行,可用于监听

文件变化相关的逻辑。

• compilation:当一个新的 Compilation 实例(负责模块解析、依赖收集、生成 chunk)被创建时

触发,是最常用的钩子之一。插件可通过此钩子获取 Compilation 实例,介入模块解析和 chunk 生成过程(如 HtmlWebpackPlugin 在此阶段生成 HTML)。

• normalModuleFactory:普通模块工厂(用于创建普通模块,如 JS 模块)初始化时触发,可用

于自定义普通模块的创建规则。

• contextModuleFactory:上下文模块工厂(用于创建上下文模块,如

require('./src/*'))初始化时触发,可用于自定义上下文模块的解析规则。

  1. 模块处理与依赖收集阶段钩子(Compilation 内部钩子)

此类钩子属于 Compilation 实例的钩子,专注于模块解析和依赖收集:

  • buildModule:开始构建一个模块时触发,可用于修改模块构建前的配置。
  • rebuildModule:重新构建一个模块时触发(如 watch 模式下模块变化)。

• moduleAsset:当一个模块生成对应的资源(如图片、CSS 文件)时触发,可用于跟踪模块与资

源的映射关系。

  • dependencyFactories:依赖工厂初始化时触发,可用于自定义依赖的创建规则。
  • dependencyTemplates:依赖模板初始化时触发,可用于自定义依赖的渲染模板。
  1. 输出阶段钩子(生成并输出 bundle 文件)

• shouldEmit:在输出文件前触发,返回 boolean 值,决定是否输出文件(返回 false 可终止

输出)。

• emit:在输出文件到磁盘前触发,是插件修改输出资源的关键钩子(如 TerserPlugin 在此阶

段压缩 JS 代码, MiniCssExtractPlugin 在此阶段提取 CSS 文件)。

• afterEmit:所有文件已输出到磁盘后触发,可用于验证输出文件、发送构建完成通知(如邮件、

钉钉通知)。

  1. 构建完成阶段钩子(编译流程结束)

• done:整个编译流程(包括输出文件)完成后触发,可用于输出构建日志、统计构建时间、清理

临时文件。

  • failed:编译流程失败时触发,可用于捕获构建错误、输出错误日志、发送错误通知。
  • invalid:仅在 watch 模式下,文件变化导致构建失效时触发,可用于提示文件变化信息。
  1. 核心钩子使用示例(插件中监听钩子)

Code block

1// 自定义简单插件,监听 compilation 和 done 钩子 2class CustomPlugin {

3apply(compiler) { 4// 监听 compilation 钩子(编译阶段)

5compiler.hooks.compilation.tap('CustomPlugin', (compilation) => {
6console.log('新的Compilation实例已创建');
7//可进一步监听Compilation内部的钩子
8compilation.hooks.buildModule.tap('CustomPlugin', (module) => {
9console.log(`开始构建模块:${module.resource}`);
10});
11});

12 13// 监听 done 钩子(构建完成)

14compiler.hooks.done.tap('CustomPlugin', (stats) => { 15console.log('构建完成,耗时:', stats.endTime - stats.startTime, 'ms');

全站分卷索引 · 26 卷
  1. 1第 1 卷
  2. 2第 2 卷
  3. 3第 3 卷
  4. 4第 4 卷
  5. 5第 5 卷
  6. 6第 6 卷
  7. 7第 7 卷
  8. 8第 8 卷
  9. 9第 9 卷
  10. 10第 10 卷
  11. 11第 11 卷
  12. 12第 12 卷
  13. 13第 13 卷
  14. 14第 14 卷
  15. 15第 15 卷
  16. 16第 16 卷
  17. 17第 17 卷
  18. 18第 18 卷
  19. 19第 19 卷
  20. 20第 20 卷
  21. 21第 21 卷
  22. 22第 22 卷
  23. 23第 23 卷
  24. 24第 24 卷
  25. 25第 25 卷
  26. 26第 26 卷