跳轉到內容

HMR hotUpdate 外掛鉤子

反饋

請在 Environment API 反饋討論區 提供反饋

我們計劃棄用 handleHotUpdate 外掛鉤子,轉而使用 hotUpdate 鉤子,以便能夠感知 環境 API (Environment API),並透過 createdelete 處理額外的監聽事件。

影響範圍:Vite 外掛開發者

未來棄用計劃

hotUpdate 最早引入於 v6.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
}

此鉤子對所有環境只調用一次,且傳入的模組僅包含來自客戶端和 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)
}

// Migrate to:

hotUpdate({ modules }) {
  return modules.filter(condition)
}

返回一個空陣列並執行完全重新載入

js
handleHotUpdate({ server, modules, timestamp }) {
  // Invalidate modules manually
  const invalidatedModules = new Set()
  for (const mod of modules) {
    server.moduleGraph.invalidateModule(
      mod,
      invalidatedModules,
      timestamp,
      true
    )
  }
  server.ws.send({ type: 'full-reload' })
  return []
}

// Migrate to:

hotUpdate({ modules, timestamp }) {
  // Invalidate modules manually
  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 []
}

// Migrate to...

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