知海

HMR hotUpdate 插件钩子变更

vite-main升级与迁移

HMR hotUpdate 插件钩子变更

::: tip 反馈
欢迎在 Environment API 反馈讨论 中给我们提出建议。

我们计划弃用 handleHotUpdate 插件钩子,转而使用 hotUpdate 钩子 以适配 Environment API,并通过 createdelete 处理额外的监听事件。

影响范围:Vite 插件作者 warning 未来弃用警告
hotUpdatev6.0 中首次引入。handleHotUpdate 的弃用计划在未来的主版本中进行。目前我们不建议立即从 handleHotUpdate 迁移。如果你想尝试新钩子并提供反馈,可以在 Vite 配置中将 future.removePluginHookHandleHotUpdate 设置为 "warn"
:::

变更动机

handleHotUpdate 钩子 允许执行自定义的 HMR 更新处理。需要更新的模块列表通过 HmrContext 传入。

ts 复制代码
interface HmrContext {
  file: string
  timestamp: number
  modules: Array<ModuleNode>
  read: () => string | Promise<string>
  server: ViteDevServer
}

该钩子对所有环境只会调用一次,传入的模块仅包含 Client 和 SSR 环境的混合信息。一旦框架迁移到自定义环境,就需要一个能为每个环境分别调用的新钩子。

新的 hotUpdate 钩子与 handleHotUpdate 的工作方式相同,但它会为每个环境分别调用,并接收一个新的 HotUpdateOptions 实例:

ts 复制代码
interface HotUpdateOptions {
  type: 'create' | 'update' | 'delete'
  file: string
  timestamp: number
  modules: Array<EnvironmentModuleNode>
  read: () => string | Promise<string>
  server: ViteDevServer
}

与其他插件钩子一样,可以通过 this.environment 访问当前开发环境。modules 列表现在只包含当前环境的模块节点。每个环境的更新可以定义不同的更新策略。

此外,该钩子现在也会响应额外的监听事件,而不仅仅是 'update' 事件。请通过 type 字段区分不同的事件类型。

迁移指南

场景一:过滤模块

按条件过滤并缩小受影响的模块列表,使 HMR 更加精准。

js 复制代码
// 迁移前
handleHotUpdate({ modules }) {
  return modules.filter(condition)
}

// 迁移后
hotUpdate({ modules }) {
  return modules.filter(condition)
}

场景二:手动失效并全量刷新

返回空数组并执行全量刷新。

js 复制代码
// 迁移前
handleHotUpdate({ server, modules, timestamp }) {
  // 手动使模块失效
  const invalidatedModules = new Set()
  for (const mod of modules) {
    server.moduleGraph.invalidateModule(
      mod,
      invalidatedModules,
      timestamp,
      true
    )
  }
  server.ws.send({ type: 'full-reload' })
  return []
}

// 迁移后
hotUpdate({ modules, timestamp }) {
  // 手动使模块失效
  const invalidatedModules = new Set()
  for (const mod of modules) {
    this.environment.moduleGraph.invalidateModule(
      mod,
      invalidatedModules,
      timestamp,
      true
    )
  }
  this.environment.hot.send({ type: 'full-reload' })
  return []
}

场景三:发送自定义事件

返回空数组,并通过向客户端发送自定义事件来执行完整的自定义 HMR 处理。

js 复制代码
// 迁移前
handleHotUpdate({ server }) {
  server.ws.send({
    type: 'custom',
    event: 'special-update',
    data: {}
  })
  return []
}

// 迁移后
hotUpdate() {
  this.environment.hot.send({
    type: 'custom',
    event: 'special-update',
    data: {}
  })
  return []
}

帮助我们改进文档

发现翻译问题或内容错误?请告诉我们。