【Vite】模块热替换 HMR

news2024/12/27 12:49:14

概述

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: Array<ModuleNamespace | undefined>) => void,
  ): void

  dispose(cb: (data: any) => void): void
  prune(cb: (data: any) => void): void
  invalidate(message?: string): void

  on<T extends string>(
    event: T,
    cb: (payload: InferCustomEventPayload<T>) => void,
  ): void
  off<T extends string>(
    event: T,
    cb: (payload: InferCustomEventPayload<T>) => void,
  ): void
  send<T extends string>(event: T, data?: InferCustomEventPayload<T>): void
}

代码结构概述

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

ImportMeta 接口

interface ImportMeta {
  readonly hot?: ViteHotContext;
}

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

ViteHotContext 接口

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

方法说明
  1. accept()

    • 用于接受模块更新。当模块更新时,Vite 将使用最新的模块重新加载。你可以提供一个回调函数来处理更新后的模块,或仅调用 accept() 以自动接受更新。
    • 示例:
      if (import.meta.hot) {
        import.meta.hot.accept((mod) => {
          console.log('模块更新了', mod);
        });
      }
      
  2. dispose(cb)

    • 注册一个回调函数,当模块被替换或页面刷新时执行。可以在这里进行资源清理或保存一些状态信息。
    • 示例:
      if (import.meta.hot) {
        import.meta.hot.dispose((data) => {
          data.someState = currentState;
        });
      }
      
  3. prune(cb)

    • 当模块被 HMR 剪枝时(意味着模块将不再被使用),会调用这个回调函数。可以用它来处理一些清理工作。
    • 示例:
      if (import.meta.hot) {
        import.meta.hot.prune(() => {
          console.log('模块已被剪枝');
        });
      }
      
  4. invalidate(message)

    • 强制使当前模块失效,并触发 HMR 更新。可以选择传递一个信息字符串,说明为什么需要失效。
    • 示例:
      if (import.meta.hot) {
        import.meta.hot.invalidate('模块需要更新');
      }
      
  5. on(event, cb)off(event, cb)

    • on 方法用于监听自定义的 HMR 事件,off 方法用于取消监听这些事件。可以通过 send 方法发送自定义事件。
    • 示例:
      if (import.meta.hot) {
        import.meta.hot.on('my-custom-event', (payload) => {
          console.log('收到自定义事件', payload);
        });
      }
      
  6. send(event, data)

    • 发送自定义 HMR 事件,并附带数据。
    • 示例:
      if (import.meta.hot) {
        import.meta.hot.send('my-custom-event', { someData: 123 });
      }
      

结合示例说明

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

<script setup>
let currentState = {count: 0}; // 初始化状态

if (import.meta.hot) {
  // 检查是否存在之前保存的状态,并进行恢复
  if (import.meta.hot.data && import.meta.hot.data.currentState) {
    currentState = import.meta.hot.data.currentState;
  }

  // 接受模块更新
  import.meta.hot.accept((mod) => {
    console.log('模块更新了', mod);
  });

  // 保存当前状态,确保在模块被替换前调用
  import.meta.hot.dispose((data) => {
    data.currentState = currentState;
  });
}

function increment() {
  currentState.count += 1;
  console.log(currentState.count);
}

</script>

<template>
  <button @click="increment">count++</button>
</template>

<style scoped>

</style>

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

项目运行:

在这里插入图片描述

模块更新:

在这里插入图片描述

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

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2047667.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

C++初学(12)

前段时间去旅游了&#xff0c;回来继续写。 12、指针、数组和指针算术 对上一篇进行的补充 #include <iostream> int main() {using namespace std;double wages[3] { 10000.0,20000.0,30000.0 };short stacks[3] { 3,2,1 };double* pw wages;short* ps &stack…

实时监控Windows服务器:使用Prometheus和Grafana的终极方案

1. 下载并安装 Prometheus 下载 Prometheus&#xff1a; 访问 Prometheus 下载页面。下载适用于 Windows 的压缩包&#xff08;.zip 文件&#xff09;。prometheus-2.53.2.windows-amd64.zip 下载其中一个就行 安装 Prometheus&#xff1a; 解压下载的压缩包到你选择的目录&a…

欧拉远程桌面 安装tigervnc

注意&#xff1a;安装远程tigevnc前提必须已经安装桌面环境&#xff0c;以下为ukui桌面环境&#xff0c;dde稍有区别&#xff1b; 1、关闭selinux 注意&#xff1a;selinux为安全措施也可以加入对应规则 setenforce 0 sed -i s/^SELINUXenforcing.*/SELINUXdisabled/ /etc/sel…

基于大模型的AI论文简报生成系统

1、项目介绍 1.1 项目名称 AI 论文简报生成系统 1.2 项目简介 AI 论文简报生成系统是一款基于当前时间自动获取最新AI研究论文简报的桌面应用程序。通过集成各类大模型Kimi、deepSeek&#xff0c;OpenAI等模型API与多步数据处理脚本&#xff0c;该系统能够在用户指定的时间…

考勤系统选型难?9款工具深度对比助你决策

这篇文章介绍的工具有&#xff1a;Moka、天时考勤管理专家、劳勤、新开普、通达OA、OnTheClock、monday.com、Paycor、Beebole。 很多企业在选择考勤管理系统时都会面临一个难题&#xff1a;市场上的选项太多&#xff0c;功能繁杂&#xff0c;如何才能找到最适合自己业务需求的…

美团外卖新版 web mtgsig 1.2 分析

声明: 本文章中所有内容仅供学习交流使用&#xff0c;不用于其他任何目的&#xff0c;抓包内容、 敏感网址、数据接口等均已做脱敏处理&#xff0c;严禁用于商业 用途和非法用途&#xff0c;否则由此产生的一切后果均与作者无关&#xff01; 有相关问题请第一时间头像或私信联…

计算机毕业设计选题推荐-牧民画像系统-Java/Python项目实战

✨作者主页&#xff1a;IT研究室✨ 个人简介&#xff1a;曾从事计算机专业培训教学&#xff0c;擅长Java、Python、微信小程序、Golang、安卓Android等项目实战。接项目定制开发、代码讲解、答辩教学、文档编写、降重等。 ☑文末获取源码☑ 精彩专栏推荐⬇⬇⬇ Java项目 Python…

SpringBoot(图书馆)自习室座位预约管理系统 - 附源码与配套论文

摘 要 在数字化转型的浪潮中&#xff0c;自习室座位预约业正积极采用先进的信息技术来优化客户体验和运营效率。本研究旨在开发一款基于Spring Boot后端框架的自习室座位预约客房预订管理系统&#xff0c;以满足现代自习室座位预约对高效、便捷、安全的预订管理需求。 座位预…

【Qt开发】QtCharts图表 在ui上添加QChartView控件并进行绘图配置

【Qt开发】QtCharts图表 在ui上添加QChartView控件并进行绘图配置 文章目录 控件安装和模块导入在ui上添加QChartView控件QChartView图表配置附录&#xff1a;C语言到C的入门知识点&#xff08;主要适用于C语言精通到Qt的C开发入门&#xff09;C语言与C的不同C中写C语言代码C语…

Simple RPC - 04 从零开始设计一个客户端(上)

文章目录 Pre设计Code1. 理解Stub“桩”的实现原理2. 动态生成桩的接口 StubFactory3. 如何来实现工厂方法创建桩动态生成“桩”类的过程步骤概述代码实现 技术点动态代理模式的应用动态代理的应用分析 依赖倒置和SPI Pre Simple RPC - 01 框架原理及总体架构初探 Simple RPC…

Postman文件上传接口测试

接口介绍 返回示例 测试步骤 1.添加一个新请求&#xff0c;修改请求名&#xff0c;填写URL&#xff0c;选择请求方式 2.将剩下的media参数放在请求body里&#xff0c;选择form-data&#xff0c;选择key右边的类型为file类型&#xff0c;就会出现选择文件的按钮Select Files&a…

继承 (上)【C++】

文章目录 继承的定义继承的语法继承权限和继承到子类后父类成员的访问限定符的变化继承到子类后父类成员的访问限定符的变化 子类继承到了父类的什么&#xff1f;继承中的作用域子类和父类之间的赋值转换子类对象可以直接赋值给父类对象&#xff0c;但是父类对象不能直接赋值给…

spring boot 接收第三方mq消息

文章目录 前言一、pom二、配置三、RabbitMQListener总结 前言 mq 用的很少&#xff0c;简单记录一下。 需求&#xff1a;数据提供方采用mq的方式推送数据&#xff0c;我方接收数据后&#xff0c;入库。 一、pom <dependency><groupId>org.springframework.boot&…

基于 Appium 的 App 爬取实战

除了运行 Appium 的基本条件外&#xff0c;还要一个日志输出库 安装&#xff1a; pip install loguru 思路分析 首先我们观察一下整个 app5 的交互流程&#xff0c;其首页分条显示了电影数据&#xff0c; 每个电影条目都包括封面&#xff0c;标题&#xff0c; 类别和评分 4…

Linux下Oracle 11g升级19c实录

1.组件信息 source /home/oracle/.bash_profile11g && sqlplus "/ as sysdba"<<EOF set line 200 col COMP_NAME for a40 select comp_name,VERSION,STATUS from dba_registry; exit; EOF COMP_NAME VERSION …

自动化之响应式Web设计:纯HTML和CSS的实现技巧

​ 大家好&#xff0c;我是程序员小羊&#xff01; 前言 响应式Web设计是一种使Web页面在各种设备和屏幕尺寸下都能良好显示的设计方法。随着移动设备的普及&#xff0c;响应式设计已经成为Web开发中的标准实践。本文将探讨如何使用纯HTML和CSS实现响应式Web设计&#xff0c;覆…

测试架构师领导力的原则

目录 一、建立信任关系 二、建立共识 三、通过关系带来安全 四、要身体力行&#xff0c;以身作则 五、适当处理风险&#xff0c;什么是鞭炮&#xff0c;什么是原子弹 测试架构师的领导力是建立在把握和执行的某些原则上---信任&#xff0c;认知&#xff0c;安全&#xff0…

Python 算法交易实验81 QTV200日常推进-重新实验SMA/EMA/RSI

说明 本次实验考虑两个点&#xff1a; 1 按照上一篇谈到的业务目标进行反推&#xff0c;有针对性的寻找策略2 worker增加计算的指标&#xff0c;重新计算之前的实验 内容 工具方面&#xff0c;感觉rabbitmq还是太慢了。看了下&#xff0c;rabbitmq主要还是面向可靠和灵活路…

【软件测试】软件系统测试方案(Word原件)

1. 引言 1.1. 编写目的 1.2. 项目背景 1.3. 读者对象 1.4. 参考资料 1.5. 术语与缩略语 2. 测试策略 2.1. 测试完成标准 2.2. 测试类型 2.2.1. 功能测试 2.2.2. 性能测试 2.2.3. 安全性与访问控制测试 2.3. 测试工具 3. 测试技术 4. 测试资源 4.1. 人员安排 4.2. 测试环境 4.2.…

Openstack 与 Ceph集群搭建(上): 规划与准备

文章目录 写在前面网络架构节点规划软件版本避坑指南 基础配置1. host配置2. 修改hostname名称3. 确保root账号能登录系统4. 配置NTP5. 配置免密登录 写在前面 近期将进行三节点的Openstack、Ceph集群混合部署&#xff0c;本人将详细记录该过程。在此之前&#xff0c;本文为Op…