<Vite>HMR实现原理

什么是HMR?

在这里插入图片描述

HMR(Hot Module Replacement)是一种开发工具,也就是热更新。用于在应用程序运行时替换、添加或删除模块,而无需完全重新加载整个页面或重新启动应用程序。这可以极大地提高开发效率和调试体验。

HMR的优势

通过使用HMR,当你修改了一个模块的代码后,在保存文件的瞬间,只有该模块及其依赖关系会被重新编译,并且新的代码将立即生效。这使得你能够实时查看对应用程序所做更改的影响结果,无需手动刷新页面。

Vite的HMR功能是通过以下原理实现的:

在这里插入图片描述

  1. ES模块和浏览器原生支持: Vite利用了现代浏览器对ES模块加载机制的支持。在开发环境中,Vite将每个文件作为一个独立的模块进行处理,并且使用浏览器自身提供的importexport语法来实现模块之间的依赖关系。

  2. WebSocket通信: 当源代码发生更改时,Vite会检测到变化并建立与客户端之间的WebSocket连接。这样,服务器可以向客户端发送更新消息。

  3. 按需编译和替换: 一旦服务器检测到代码更改,它会根据变化重新编译受影响的文件,并生成新版本。然后,服务器通过WebSocket将更新消息发送给客户端。

  4. 局部更新: 客户端收到更新消息后,它会根据需要下载新版本并对页面进行局部刷新,而无需完全重新加载整个页面。这种局部刷新使得应用程序保持在开发状态下无缝运行,并提供快速反馈。

具体而言,在Vite中实现HMR特性主要涉及以下三个步骤:

  1. 监听文件改动: 在开发模式下,Vite使用一个文件系统监视器(watcher)来监听源代码文件的变化。当文件被修改、添加或删除时,watcher会立即捕获到这些变化。

  2. 服务器端编译资源并推送新模块内容给浏览器: 一旦有文件更改被捕获,Vite启动一个服务器,并执行相应的编译过程。它会根据需要重新构建受影响的模块,并生成新版本。然后,服务器通过WebSocket与客户端保持连接,并将更新消息推送给浏览器。

  3. 浏览器接收并处理新模块内容: 浏览器收到更新消息后,在不刷新整个页面的情况下下载和加载新版本的模块。对于支持HMR功能的前端框架(如Vue.js和React),它们具备能力在接收到新模块内容后进行局部渲染或组件重载操作(例如Vue中即是rerender)。这使得应用程序可以实现热更新效果,即时地反映出源代码更改所带来的变化。

serverPluginClient 源码举例

serverPluginClient是Vite中的一个插件,用于在开发服务器上提供客户端代码。它负责将构建后的客户端代码发送给浏览器,并处理与客户端相关的请求。

服务端由 serverPluginClient 插件进行处理
代码举例:

export const clientPlugin: ServerPlugin = ({ app, config }) => {
  // 读取客户端代码文件内容,并替换其中的占位符
  const clientCode = fs
    .readFileSync(clientFilePath, 'utf-8')
    .replace(`__MODE__`, JSON.stringify(config.mode || 'development'))
    .replace(
      `__DEFINES__`,
      JSON.stringify({
        ...defaultDefines,
        ...config.define
      })
    )

  // 使用中间件处理请求
  app.use(async (ctx, next) => {
    if (ctx.path === clientPublicPath) {
      ctx.type = 'js'
      ctx.status = 200

     // 返回具体内容,将端口号动态替换到客户端代码中的占位符处
     ctx.body = clientCode.replace(`__PORT__`, ctx.port.toString())

   } else {

     // 兼容历史逻辑,并进行错误提示
     if (ctx.path === legacyPublicPath) {
       console.error(
         chalk.red(
           `[vite] client import path has changed from "/vite/hmr" to "/vite/client". ` +
             `please update your code accordingly.`
         )
       )
     }
     
     return next()
   }
 })
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【uniapp】微信小程序,取视频第一帧,前提是 图片是在 阿里云的oss上

上传视频等,默认为黑色,无法用视频的第一帧作为封面,以及视频的video为原生组件,层级很高无法覆盖问题,虽然有cover-view,但很多场景还是不灵活 实现的前提条件是 图片是在 阿里云的oss上 自己服务器是…

在线Word怎么转换成PDF?Word无法转换成PDF文档原因分析

不同的文件格式使用方法是不一样的,而且也需要使用不同的工具才可以打开编辑内容,针对不同的场合用户们难免会用到各种各样的文件格式,要想在不修改内容的前提下提高工作效率,那就需要用到文件格式转换,那么在线Word怎…

Springboot 实践(1)MyEclipse2019创建maven工程

项目讲解步骤,基于本机已经正确安装Java 1.8.0及MyEclipse2019的基础之上,Java及MyEclipse的安装,请参考其他相关文档,Springboot 实践文稿不再赘述。项目创建讲解马上开始。 一、首先打开MyEclipse2019,进入工作空间选…

bash: make: command not found

make之后报错信息如下:cd 对应的文件路径后 make 发现报错:bash: make: command not found 这个原因可能是没有安装make工具,也可能是安装了make之后,没有将make的文件路径添加到系统环境变量中 有没有安装make,可以使用Search Everything搜索是否有make…

【实战项目】c++实现基于reactor的高并发服务器

基于Reactor的高并发服务器,分为反应堆模型,多线程,I/O模型,服务器,Http请求和响应五部分 ​全局 反应堆模型 Channel 描述了文件描述符以及读写事件,以及对应的读写销毁回调函数,对应存储ar…

最强自动化测试框架Playwright(18)- 执行js脚本

page.evaluate() API 可以在网页上下文中运行 JavaScript 函数,并将结果带回 Playwright 环境。 href page.evaluate(() > document.location.href) 如果结果是 Promise 或函数是异步的,则计算将自动等待,直到解析…

IDEA如何调试Stream API

Stream API现在在实际开发中应用非常广泛,经常会遇到需要调试Stream API的场景,这篇文章主要讲解如何使用IDEA调试Stream Testpublic void test(){Stream.of(10, 20, 30, 40, 50).mapToInt(e->e*10).filter(e->e>200).forEach(System.out::pri…

第八章 CUDA内存应用与性能优化篇(上篇)

cuda教程目录 第一章 指针篇 第二章 CUDA原理篇 第三章 CUDA编译器环境配置篇 第四章 kernel函数基础篇 第五章 kernel索引(index)篇 第六章 kenel矩阵计算实战篇 第七章 kenel实战强化篇 第八章 CUDA内存应用与性能优化篇 第九章 CUDA原子(atomic)实战篇 第十章 CUDA流(strea…

0基础学C#笔记09:希尔排序法

文章目录 前言一、希尔排序的思想二、使用步骤总结 前言 希尔排序可以说是插入排序的一种变种。无论是插入排序还是冒泡排序,如果数组的最大值刚好是在第一位,要将它挪到正确的位置就需要 n - 1 次移动。也就是说,原数组的一个元素如果距离它…

优维低代码实践:自定义模板

优维低代码技术专栏,是一个全新的、技术为主的专栏,由优维技术委员会成员执笔,基于优维7年低代码技术研发及运维成果,主要介绍低代码相关的技术原理及架构逻辑,目的是给广大运维人提供一个技术交流与学习的平台。 优维…

此文详解,数据仓库管理建设的经验

目前由于数据分散在不同的存储环境或数据库中,对于新业务需求的开发需要人工先从不同的数据库中同步、集中、合并等处理,造成资源和人力的浪费。同时,目前的系统架构,无法为未来数据驱动业务创新的理念提供友好的支撑。需要建设新…

如何构建一个 NodeJS 影院微服务并使用 Docker 部署

文章目录 前言什么是微服务?构建电影目录微服务构建微服务从 NodeJS 连接到 MongoDB 数据库总结 前言 如何构建一个 NodeJS 影院微服务并使用 Docker 部署。在这个系列中,将构建一个 NodeJS 微服务,并使用 Docker Swarm 集群进行部署。 以下…

d3dcompiler43.dll缺失怎么修复?dll缺失解决方法分享

在使用电脑过程中,我们有时会遇到一些系统文件的问题,其中一个常见的问题是d3dcompiler43.dll文件的损坏或丢失。当这个文件出现问题时,可能会导致应用程序无法正常运行或图形渲染出现异常。最近我也遇到了这个问题,以下是我修复d…

安达发APS|生产计划排产软件助力加工制造业智能化转型

随着全球经济一体化的不断深入,市场竞争日益激烈,加工制造企业面临着巨大的生存压力。在这种情况下,企业对于生产计划的精细化管理需求日益迫切。为了适应这一市场需求,安达发推出了专门针对加工企业的APS生产计划排产软件&#x…

机器学习实战5-KMeans聚类算法

文章目录 概述KMeansKMeans参数&接口n_clusters质心inertia模型评估指标轮廓系数Calinski-Harabaz Index 重要参数init & random_state & n_init:初始质心怎么放好?重要参数max_iter & tol:让迭代停下来重要属性与重要接口 概述 聚类 …

Linux之awk判断和循环

echo zhaoy 70 72 74 76 74 72 >> score.txt echo wangl 70 81 84 82 90 88 >> score.txt echo qiane 60 62 64 66 65 62 >> score.txt echo sunw 80 83 84 85 84 85 >> score.txt echo lixi 96 80 90 95 89 87 >> score.txt把下边的内容写入到s…

大语言模型(LLM)与 Jupyter 连接起来了

现在,大语言模型(LLM)与 Jupyter 连接起来了! 这主要归功于一个名叫 Jupyter AI 的项目,它是官方支持的 Project Jupyter 子项目。目前该项目已经完全开源,其连接的模型主要来自 AI21、Anthropic、AWS、Co…

优雅地处理RabbitMQ中的消息丢失

目录 一、异常处理 二、消息重试机制 三、错误日志记录 四、死信队列 五、监控与告警 优雅地处理RabbitMQ中的消息丢失对于构建可靠的消息系统至关重要。下面将介绍一些优雅处理消息丢失的方案,包括异常处理、重试机制、错误日志记录、死信队列和监控告警等。…

Go Gin 中使用 JWT

一、JWT JWT全称JSON Web Token是一种跨域认证解决方案,属于一个开放的标准,它规定了一种Token实现方式,目前多用于前后端分离项目和OAuth2.0业务场景下。 二、为什么要用在你的Gin中使用JWT 传统的Cookie-Sesson模式占用服务器内存, 拓展性…

QT 使用第三方库QtXlsx操作Excel表

1.简介 一直以来,都想学习一下C/C如何操作excel表,在网上调研了一下,觉得使用C/C去操作很麻烦,遂转向QT这边;QT有一个自带的类QAxObject,可以使用他去操作,但随着了解的深入,觉得他…