• 作者:老汪软件技巧
  • 发表时间:2024-08-20 17:05
  • 浏览量:

概述

Vite 提供了一套原生 ESM 的HMR API。 具有 HMR 功能的框架可以利用该 API 提供即时、准确的更新,而无需重新加载页面或清除应用程序状态。当通过create-vite创建应用程序时,所选模板已经预先配置了相关的集成。

HMR API

Vite 通过特殊的import.meta.hot对象暴露手动 HMR API。

interface ImportMeta {
  readonly hot?: ViteHotContext
}
interface ViteHotContext {
  readonly data: any
  accept(): void
  accept(cb: (mod: ModuleNamespace | undefined) => void): void
  accept(dep: string, cb: (mod: ModuleNamespace | undefined) => void): void
  accept(
    deps: readonly string[],
    cb: (mods: Arrayundefined>) => void,
  ): void
  dispose(cb: (data: any) => void): void
  prune(cb: (data: any) => void): void
  invalidate(message?: string): void
  onextends string>(
    event: T,
    cb: (payload: InferCustomEventPayload) => void,
  ): void
  offextends string>(
    event: T,
    cb: (payload: InferCustomEventPayload) => void,
  ): void
  sendextends string>(event: T, data?: InferCustomEventPayload): void
}

代码结构概述

代码中定义了两个接口:ImportMeta 和 ViteHotContext。ImportMeta 是在模块上下文中使用的,ViteHotContext 则是 Vite 的 HMR 相关的接口,包含了一些允许你在模块更新时执行特定操作的方法。

ImportMeta 接口

interface ImportMeta {
  readonly hot?: ViteHotContext;
}

hot 属性是 ViteHotContext 类型的可选属性。当 Vite 在开发模式下运行时,这个属性会被填充,用于处理 HMR 相关操作。如果你在生产环境或 HMR 未启用的情况下访问 import.meta.hot,它将是 undefined。

ViteHotContext 接口

ViteHotContext 定义了与 HMR 相关的各种方法,这些方法用于处理模块的更新、清理以及自定义事件。

方法说明

accept()

模块切换__如何更换模块

dispose(cb)

prune(cb)

invalidate(message)

on(event, cb) 和 off(event, cb)

send(event, data)

结合示例说明

假设在一个项目中使用了一个组件,并且希望在组件更新时能保存它的状态,代码如下:


<template>
  <button @click="increment">count++button>
template>
<style scoped>
style>

在这个示例中,通过 dispose 方法保存组件的状态,并在模块更新后通过 accept 方法重新加载模块时恢复该状态。这就避免了在模块热更新时丢失状态。

项目运行:

模块更新:

如果将外部引入的模块删掉并保存,则会显示 page reload,也就是页面重新刷新了一下。

hmr 只会在开发环境生效( 生产环境 import.meta.hot 为 undefined ),在生产环境里边它是不存在的。就会被 tree shaking 给优化掉。