vite 底层解析

news2024/11/17 7:17:54

vite

目前大多数框架的前端构建工具都已经被vite取代,相信你已经使用过vite了。可是在使用过程中,vite对我来说一直是模糊的,现在就来一探究竟,为啥它更好?
接下来我将为从以下几点出发,究其原理

一、原生ES模块

1、Common JS

  • 文件即模块,每一个文件都是一个 Module 实例,所有代码都运行带模块作用域,不会污染全局作用域(因为CommonJS 输出的是值的拷贝)
  • 所有文件运行时同步加载,模块加载的顺序是按照其在代码中出现的顺序,加载完再执行。
  • 每个模块加载一次后就会被缓存。后续require时,①先检查缓存中是否存在,②如果缓存中没有,检查是否是核心模块,如果是就直接加载,③如果不是核心模块,检查是否是文件模块,解析路径,根据解出的路径定位文件,然后执行,④如果以上都不是,沿当前路径向上级逐级递归,直到根目录的 node_modules 目录
  • CommonJS 模块直接放在浏览器中是无法执行的,所以要想在浏览器中运行,需要使用额外的工具(browserify

2、ES Module

  • 浏览器支持: ES6 Module 也被成为 ES Module,是由ESMAScript 官方提出的模块化规范。目前已经得到了现代浏览器的支持。如果在HTML中加入type ="module"属性的 script 标签,那么浏览器会按照 ES Module 规范来进行以来加载和模块解析,这也是 vite 在开发阶段实现 no-bundle 的原因。由于浏览器可以加载模块,所以即使不打包可以顺利运行模块代码。
  • 动态导入,按需加载
<script type="module">
 (async () => {
   const moduleSpecifier = './lib.mjs';
   const {repeat, shout} = await import(moduleSpecifier);
   repeat('hello');
   // → 'hello hello'
   shout('Dynamic import in action');
   // → 'DYNAMIC IMPORT IN ACTION!'
 })();
</script>
  • import map:支持绝对路径(www.baidi.com)、相对路径(./module),同时支持直接写一个第三方包名,如 react、lodash。前两种都是浏览器原生支持的,但是对于第三中,放在浏览器中是无法直接执行的,ESM 解决了这个问题,这里不详细解释,可自行搜索

vite 利用浏览器对原生ES模块的支持,采用按需加载的方式,每次请求一个模块,Vite仅仅返回该模块的内容,而不是整个应用的捆绑文件。
但是!webpack是通过捆绑的方式,将所有模块打包成一个或多个文件,这意味着什么,意味着我们在启动项目是需要对整个应用进行打包,会导致长时间的等待

二、预构建

1、预构建解决了什么问题

  • 将其他格式(例如 UMD 、CommonJS)的产物转换为 ESM 格式,使其在浏览器通过 <script type = "module"><script/> 的方式正常加载。举个例子:大名鼎鼎的 React 就是基于 CommonJS ,而这种格式在vite中是无法直接运行的,但是Vite 没有办法限制第三方的规范,所以改变不了别人,那就改变自己,内部转换
  • 打包第三方库的代码,将各个第三方库分散的文件合并在一起,减少 HTTP 请求,避免页面加载性能劣化。举个例子:loadsh-es 是ES 版本,vite可以直接运行,但实际上,在它加载时会发出特别多的请求,导致页面加载的前几秒几乎处于卡顿状态。每次 import 都会触发一个新的文件请求,如果不加控制,会触发成百上千个网络请求,而 Chrome 对同一个域名在只能同时支持 6 个 HTTP 并发请求,导致页面加载十分缓慢。在加入依赖预构建之后,loadsh-es 的代码被打包成一个文件,这样请求的数量会减少很多,减轻浏览器压力,页面加载速度变快。

三、双引擎(EsBuild 和 Rollup)

1、EsBuild 预构建

esbuild 在 Vite 中的作用集中在提升构建速度、优化依赖处理和简化开发体验

  • 快速构建
    esbuild 是用 go 编写的构建工具,具有极快的编译速度。使得 Vite 在开发环境中可以快速响应文件变更,提供及时反馈
  • 多核并存
    js 是单线程串行,esbuild 直接新开一个线程 ,多线程并行,充分发挥多核优势
  • 代码压缩,减少内存
    esbuild 提供了一个 minify 配置允许用户去压缩代码体积

2、Rollup 打包

vite 选择在生产环境中利用Rollup打包,并基于Rollup 本身成熟的打包能力进行扩展和优化

  • css代码分割。如果某个异步模块中引入了一些 CSS 代码,Vite 就会自动将这些 CSS 抽取出来生成单独的文件,提高线上产物的缓存复用率。
  • 自动预加载。Vite 会自动为入口 chunk 的依赖自动生成预加载标签。这种适当预加载的做法会让浏览器提前下载好资源,优化页面性能。
  • 异步Chunks 加载优化。在异步引入的 Chunk 中,通常会有一些公用的模块,如现有两个异步引入的 Chunk: A 和 B,而且两者有一个公共依赖 C一般情况下,Rollup 打包之后,会先请求 A,然后浏览器在加载 A 的过程中才决定请求和加载 C,但 Vite 进行优化之后,请求 A的同时会自动预加载 C,通过优化 Rollup 产物依赖加载方式节省了不必要的网络开销。
  • 多产物配置。同一个入口文件,打包出多种格式的产物
const buildOptions = {
  input: ["src/index.js"],
  // 将 output 改造成一个数组
  output: [
    {
      dir: "dist/es",
      format: "esm",
    },
    {
      dir: "dist/cjs",
      format: "cjs",
    },
  ],
};

export default buildOptions;
  • 多入口配置,将 input 设置为一个数组或者一个对象:
{
  input: ["src/index.js", "src/util.js"]
}
// 或者
{
  input: {
    index: "src/index.js",
    util: "src/util.js",
  },
}

四、热模块更新(HMR)

vite 热更新过程

  1. 创建一个 websocket 服务端和 client 文件,启动服务
  2. 通过 chokidar 监听文件变更
  3. 当代码变更后,服务端进行判断并推送到客户端
  4. 客户端根据推荐的信息执行不同操作的更新
    在这里插入图片描述

webpack 热更新过程

  1. 使用 webpack-dev-server (后面简称 WDS)托管静态资源,同时以 Runtime 方式注入一段处理 HMR 逻辑的客户端代码;
  2. 浏览器加载页面后,与 WDS 建立 WebSocket 连接;
    Webpack 监听到文件变化后,增量构建发生变更的模块,
  3. 通过 WebSocket 发送 hash 事件;
  4. 浏览器接收到 hash 事件后,请求 manifest 资源文件,确认增量变更范围;
  5. 浏览器加载发生变更的增量模块;
  6. Webpack 运行时触发变更模块的 module.hot.accept 回调,执行代码变更逻辑;
  7. done。

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

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

相关文章

基于大数据技术的智慧居家养老服务平台

作者&#xff1a;计算机学姐 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等&#xff0c;“文末源码”。 专栏推荐&#xff1a;前后端分离项目源码、SpringBoot项目源码、Vue项目源码、SSM项目源码 精品专栏&#xff1a;Java精选实战项目…

Redis实战篇-短信登入

Redis实战篇-短信登入 该笔记是来源于黑马程序员的Redis项目课程,为了后续方便复习。将笔记记录在博客之中 实战篇我们要学习一些什么样的内容 1.本期任务 短信登录 使用redis共享session来实现 商户查询缓存 理解缓存击穿&#xff0c;缓存穿透&#xff0c;缓存雪崩等问题 …

基于冲突动态监测算法的健身房预约管理系统

系统展示 用户前台界面 管理员后台界面 系统背景 随着健身热潮的兴起&#xff0c;健身房管理面临着日益增长的会员需求与资源分配的挑战。传统的人工预约方式不仅效率低下&#xff0c;且容易出现时间冲突和资源浪费的情况。为了解决这一问题&#xff0c;基于冲突动态监测算法的…

【CSS/HTML】CSS实现两列布局,一列固定宽度,一列宽度自适应方法

文章目录 1.固定宽度区浮动&#xff0c;自适应区不设宽度而设置 margin2.float与margin配合使用3.固定宽度区使用绝对定位&#xff0c;自适应区设置margin4.使用display:table实现 不管是左是右&#xff0c;反正就是一边宽度固定&#xff0c;一边宽度自适应。 博客的很多主题也…

Python学习(3):画散点图和箱线图

1. 散点图&#xff08;matplotlib库&#xff09; 1.1 代码示例 import matplotlib.pyplot as plt# 准备数据 x [1, 2, 3, 4, 5] y [2, 4, 6, 8, 10]# 绘制散点图 plt.scatter(x, y)# 添加标题和标签 plt.title("散点图示例") plt.xlabel("X 轴") plt.y…

Android PopupWindow.showAsDropDown报错:BadTokenException: Unable to add window

Android PopupWindow.showAsDropDown报错&#xff1a;BadTokenException: Unable to add window Android PopupWindow.showAsDropDown报错&#xff1a; android.view.WindowManager$BadTokenException: Unable to add window -- token null is not valid; is your activity ru…

【华为HCIP实战课程一】OSPF相关基础介绍及基础配置,网络工程师必修

一、OSPF介绍 开放式最短路径优先协议OSPF(Open Shortest Path First),IPv4使用的OSPFv2,针对IPv6使用OSPFv3协议。 二、为什么需要OSPF OSPF出现之前,网络广泛使用RIP路由协议,RIP由于最大16跳数限制无法适应大型网络,RIP是基于距离矢量算法的路由协议,应用在大型网…

MySQL使用FROM_UNIXTIME转换时间戳timestamp无效问题原因

问题点在于timestamp的长度&#xff0c;检查下存储在数据库里的时间戳的数据格式及长度。 MySQL的FROM_UNIXTIME函数默认处理的是10位的时间戳&#xff0c;不是10位就会出现无效的情况&#xff0c;但是数据库并不会进行异常提示。 一般情况下&#xff0c;普遍遇到的是10位或者…

VSCode调试Electron

使用vscode来调试electron主进程&#xff0c;实现断点调试、监视变量&#xff0c;跟踪代码执行&#xff0c;极大地提高开发效率。 在vscode代码编辑器中左侧找到运行或调试 上方下拉框添加配置 点击添加配置后&#xff0c;会在根目录的.vscode目录下存在launch.json文件&am…

阿里云部署1Panel(失败版)

官网脚本部署不成功 这个不怪1panel,这个是阿里Linux 拉不到docker的下载源,懒得思考 正常部署直接打开官网 https://1panel.cn/docs/installation/online_installation/ 但是我使用的阿里云os(Alibaba Cloud Linux 3.2104 LTS 64位) 我执行不管用啊装不上docker 很烦 curl -s…

Android中使用RecyclerView制作横向轮播列表及索引点

在Android开发中&#xff0c;RecyclerView是一个非常强大的组件&#xff0c;用于展示列表数据。它不仅支持垂直滚动&#xff0c;还能通过配置不同的LayoutManager实现横向滚动&#xff0c;非常适合用于制作轮播图或横向列表。本文将详细介绍如何使用RecyclerView在Android应用中…

【中间件——基于消息中间件的分布式系统的架构】

1. 基于消息中间件的分布式系统的架构 从上图中可以看出来&#xff0c;消息中间件的是 1&#xff1a;利用可靠的消息传递机制进行系统和系统直接的通讯 2&#xff1a;通过提供消息传递和消息的排队机制&#xff0c;它可以在分布式系统环境下扩展进程间的通讯。 1.1 消息中间件…

PaddleOCR 表格识别,docker部署,cpu版本

前置环境 centeros7 docker 拉取镜像 docker pull registry.baidubce.com/paddlepaddle/paddle:2.6.1 参考&#xff1a;开始使用_飞桨-源于产业实践的开源深度学习平台 这里拉取的镜像并不能立马用&#xff0c;只是内置好运行环境 随便找个目录下载paddleocr的代码 git…

Ubuntu/Debian网络配置(补充篇)

Ubuntu/Debian网络配置补充 在《Ubuntu/Debian网络配置 & Ubuntu禁用自动更新_ubuntu nmtui-CSDN博客》上总结的“配置网络”章节&#xff0c;对于新版本或者“最小化安装”场景&#xff0c;可能不适应&#xff0c;故此本文做一下补充&#xff0c;就不在原有文章上做更新了…

【友元补充】【动态链接补充】

友元 友元的目的是让一个函数或者类&#xff0c;访问另一个类中的私有成员。 有缘的关键字friend是一个修饰符。 友元分为友元类和友元函数 1.全局函数作友元 2.类作友元 3.类的一个成员函数作友元 好处&#xff1a;可以通过友元在类外访问类内的私有和受保护类型的成员 坏处…

在树莓派上基于 LNMP 搭建 Nextcloud

原文链接&#xff1a;https://blog.iyatt.com/?p17296 环境 树莓派CM4raspios 20240704 Debian 12 arm64 搭建 LNMP 环境 安装 Nginx sudo apt update sudo apt install -y nginx安装 php 及功能组件支持 参考&#xff1a;https://docs.nextcloud.com/server/latest/adm…

【高分系列卫星简介——高分辨率多模综合成像卫星】

高分辨率多模综合成像卫星 高分辨率多模综合成像卫星&#xff08;以下简称“高分多模卫星”&#xff09;是中国航天科技集团所属中国空间技术研究院抓总负责研制的具备亚米级分辨率的民用光学遥感卫星。以下是对高分多模卫星的详细介绍&#xff1a; 一、基本信息 发射时间&…

打造备份一体机,群晖科技平台化战略再进阶

数字经济时代&#xff0c;海量数据不断涌现&#xff0c;并成为核心生产要素&#xff0c;驱动着企业生产方式和商业模式发生深刻变革。 与其他生产要素不同&#xff0c;数据要素具有非稀缺性、非竞争性等特征&#xff0c;且只有在具体业务场景中才能充分释放其价值。尤其是近年…

AIGC: 10 AI转文服务器的搭建过程记录

上图是台风席卷城市&#xff0c;现在企业的服务基本都是混合部署&#xff0c;云计算厂商的机房往往可以提供比较好的保护&#xff0c;一般在地下&#xff0c;扛多少级地震&#xff0c;扛多少级台风&#xff0c;而自建机房&#xff0c;往往写字楼经常停电&#xff0c;网络运营上…

MapBox Android版开发 6 关于Logo

MapBox Android版开发 6 关于Logo Logo的显示查看源码及思路&#xff08;Logo&#xff09;第一步第二步 隐藏Logo示例查看源码及思路&#xff08;Info&#xff09;第一步第二步 隐藏Logo和Info示例 看到有网友留言问如何移除Logo&#xff0c;今天看了下V9源码&#xff0c;发现M…