Vite 原理浅析

Vite 原理浅析Vite 有如下特点 快速的冷启动 NoBundle esbuild 预构建即时的模块热更新 基于 ESM 的 HMR 同时利用浏览器缓存策略提升速度真正的按需加载 利用浏览器 ESM 支持 实现真正的按需加载 Vite 相比于 Webpack 而言 没有打包的过程 而是直接启动了一个开发服务器 devServer Vite 劫持浏览器的 HTTP 请求 在后端进行相应的处理将项目中使用的文件通过简单的分解与整合 然后再返回给浏览器 整个过程没有对文件进行打包编译 所以编译速度很快 Vite 直接整合了

在这里插入图片描述

Vite有如下特点:

  • 快速的冷启动: No Bundle + esbuild 预构建
  • 即时的模块热更新: 基于ESM的HMR,同时利用浏览器缓存策略提升速度
  • 真正的按需加载: 利用浏览器ESM支持,实现真正的按需加载

Vite相比于Webpack而言,没有打包的过程,而是直接启动了一个开发服务器devServer。Vite劫持浏览器的HTTP请求,在后端进行相应的处理将项目中使用的文件通过简单的分解与整合,然后再返回给浏览器(整个过程没有对文件进行打包编译)。所以编译速度很快。

Vite 直接整合了 Rollup,为用户提供了完善、开箱即用的解决方案,在需要bundle打包的时候Vite 使用 Rollup 内置配置。

ESM是JavaScript提出的官方标准化模块系统,不同于之前的CJS,AMD,CMD等等,ESM提供了更原生以及更动态的模块加载方案,最重要的就是它是浏览器原生支持的,也就是说我们可以直接在浏览器中去执行import,动态引入我们需要的模块,而不是把所有模块打包在一起

当我们在使用模块开发时,其实就是在构建一张模块依赖关系图,当模块加载时,就会从入口文件开始,最终生成完整的模块实例图。

ESM的执行可以分为三个步骤:

  1. 构建: 确定从哪里下载该模块文件、下载并将所有的文件解析为模块记录
  2. 实例化: 将模块记录转换为一个模块实例,为所有的模块分配内存空间,依照导出、导入语句把模块指向对应的内存地址
  3. 运行:运行代码,将内存空间填充

ESM使用实时绑定的模式,导出和导入的模块都指向相同的内存地址,也就是值引用。而CJS采用的是值拷贝,即所有导出值都是拷贝值。

Vite 核心原理

Vite其核心原理是利用浏览器现在已经支持ES6的import,碰见import就会发送一个HTTP请求去加载文件。Vite启动一个 connect 服务器拦截这些请求,并在后端进行相应的处理将项目中使用的文件通过简单的分解与整合,然后再以ESM格式返回返回给浏览器。整个过程中没有对文件进行打包编译。

Webpack是先解析依赖、打包构建再启动开发服务器,Dev Server 必须等待所有模块构建完成,当我们修改了 bundle模块中的一个子模块, 整个 bundle 文件都会重新打包然后输出。项目应用越大,启动时间越长。

而 Vite利用浏览器对ESM的支持,当 import 模块时,浏览器就会下载被导入的模块。先启动开发服务器,当代码执行到模块加载时再请求对应模块的文件,本质上实现了动态加载。

目前所有的打包工具实现热更新的思路都大同小异:主要是通过WebSocket创建浏览器和服务器的通信监听文件的改变,当文件被修改时,服务端发送消息通知客户端修改相应的代码,客户端对应不同的文件进行不同的操作的更新。

Vite 通过 chokidar 来监听文件系统的变更,只用对发生变更的模块重新加载, 只需要精确的使相关模块与其临近的 HMR边界连接失效即可,这样HMR 更新速度就不会因为应用体积的增加而变慢。

热更新流程

Vite整个热更新过程可以分成四步:

  1. 创建一个websocket服务端和client文件,启动服务
  2. 通过chokidar监听文件变更
  3. 当代码变更后,服务端进行判断并推送到客户端
  4. 客户端根据推送的信息执行不同操作的更新
  • 启动热更新:createWebSocketServer: 在 Vite dev server 启动之前,Vite 会为 HMR 做一些准备工作:比如创建websocket服务,利用chokidar创建一个监听对象 watcher 用于对文件修改进行监听等等。createWebSocketServer这个方法主要是创建WebSocket服务并对错误进行一些处理,最后返回封装好的on、off、 send 和 close 方法,用于后续服务端推送消息和关闭服务
  • 执行热更新:moduleGraph+handleHMRUpdate模块。接收到文件改动执行的回调,这里主要两个操作:moduleGraph.onFileChange修改文件的缓存和handleHMRUpdate执行热更新。moduleGraph 是Vite定义的用来记录整个应用的模块依赖图的类,除此之外还有moduleNode。moduleGraph是由一系列 map 组成,而这些map分别是url、id、file等与ModuleNode的映射,而ModuleNode 是 Vite中定义的最小模块单位。
  • handleHMRUpdate: 主要是监听文件的更改,进行处理和判断通过WebSocket给客户端发送消息通知客户端去请求新的模块代码。

预编译原理

Vite预编译之后,将文件缓存在node_modules/.vite/文件夹下。根据以下地方来决定是否需要重新执行预构建。

  • package.json中:dependencies发生变化
  • 包管理器的lockfile

如果想强制让Vite重新预构建依赖,可以使用–force启动开发服务器,或者直接删掉node_modules/.vite/文件夹。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/222677.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月17日 下午3:13
下一篇 2026年3月17日 下午3:14


相关推荐

  • 网页刷流量软件开发中的困惑

    网页刷流量软件开发中的困惑客户要求:1.利用代理IP访问指定网页.并且点击指定位置2.代理IP获取方式最好为吸附.吸附我提供的地址.或许你有更好的方案最佳.3.如果能够控制代理访问量最好.比如我在指定的时间内10点-11点的时候需要1W的量.那么程序刷到1W的量就自动停止.4.可以用协议开发.但是协议一定要支持统计代码.也就是一定要让后台统计到具体数据.我的解决方案有二:。一是模…

    2026年4月18日
    4
  • 关于力矩单位的理解

    关于力矩单位的理解电机转矩,简单的说,就是指转动的力量的大小。但电动机的转矩与旋转磁场的强弱和转子笼条中的电流成正比,和电源电压的平方成正比所以转矩是由电流和电压的因素所决定的。转矩是一种力矩,力矩在物理中的定义是:力矩=力×力臂电机的“扭矩”,单位是N·m(牛米)。电磁转矩的计算公式没有涉及力臂的概念,单位为什么也是N.m?电磁转矩是机电能量转换的桥梁。从电角度看T=CT*Φ*Ia;从机

    2022年5月14日
    55
  • Linux Socket 编程原理详解

    Linux Socket 编程原理详解不用多说,经典的TCP/IP三次握手及状态变迁图================================================================================================================函数:socket()–创建套接字,它会创建一个结构体及收发缓冲区。此时并不指定该套接字在哪个IP和PORT口上,bind()–用于将套接字绑定在特定的IP/PORT上listen()–用于为侦听端口创建两个队列(见上图

    2022年10月17日
    4
  • 50个概率题

    50个概率题1 袜子抽屉一个抽屉有红袜子和黑袜子 随机取出两支袜子都是红袜子的概率是 0 5 a 抽屉里最少有几只袜子 b 如果抽屉中黑袜子的数量是偶数 抽屉里最少有几只袜子 a 4 b 212 连胜为了激励小明的网球生涯 如果他在三盘中连赢 2 盘 他爹就给他奖励 小明每盘可从他爹和俱乐部冠军中选一个作为对手 但不能连续选择一个人 2 次 即 爹 冠军 爹 或 冠军 爹 冠军 冠军的水平比他爹高

    2026年3月19日
    3
  • OJ平台各个简写的含义

    OJ平台各个简写的含义简写字符的含义简写全称中文称谓ACAccepted通过WAWrongAnswer答案错误TLETimeLimitExceed超时OLEOutputLimitExceed超出输出限制MLEMemoryLimitExceed超出内存RERuntimeError运行时错误PEPresentationError格式错误CECompileError无法编译…

    2022年6月22日
    31
  • jQuery中delegate与on的用法与区别

    jQuery中delegate与on的用法与区别在 jQuery1 7 中 delegate 已被 on 取代 对于早期版本 它仍然使用事件委托的最有效手段 在事件绑定和委派 delegate 和 on 在一般情况下 这两种方法是等效的 delegate 指定的元素 属于被选元素的子元素 添加一个或多个事件处理程序 并规定当这些事件发生时运行的函数 jQuery1 4 3 elements dele

    2026年3月26日
    2

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号