发布于: 2025-2-20最后更新: 2025-2-20字数 2616阅读时长 7 分钟

type
status
date
slug
summary
tags
category
icon
password

什么是Vite

♻️
对我个人来说,我觉得这点很重要,不管是你在面试的时候,还是在自身理解的时候,都应该明确
首先,vite是一个前端构建工具,还包括webpack,可以提高开发体验。由两个步骤组成
  • 开发服务器
    • 对于开发,最大的优势就是基于原生ES模块提供丰富内建功能,可以提高我们的开发效率,具有非常好的HMR(热更新)
👉
ESModule是一种 JavaScript 模块化机制,它在 ECMAScript 2015(ES6)中被正式标准化,目的是为了更好地组织和管理代码,将复杂的应用拆分成多个文件或模块。

主要特点

  1. 静态结构
      • 静态分析: ESModule 的引入和导出语句(import / export)在编译阶段就可以确定,因为它们不能动态地改变。这使得构建工具(如 Webpack、Vite 等)能更有效地进行 Tree Shaking,剔除未使用的代码模块。
  1. 严格模式默认开启
      • 使用 ESModule 的代码会默认以严格模式运行,不需要手动声明 "use strict"
  1. 模块作用域
      • 每个 ESModule 文件都有自己的作用域,定义在模块内部的变量和函数不会污染全局命名空间。
  1. 明确的依赖关系
      • 通过 import 显式声明依赖关系,使代码结构更清晰,同时也便于静态分析和优化。

基本语法示例

  • 导出(Export):
    • 导入(Import):

      与其他模块化系统的对比

      • CommonJS:
        • Node.js 曾经主要使用 CommonJS 模块规范(如使用 requiremodule.exports),而 ESModule 通过静态的 import/export 能在编译时完成依赖分析,性能上和可优化性上更具优势。
      • AMD(Asynchronous Module Definition):
        • 主要用于浏览器端,利用异步加载模块,但写法较为冗长。ESModule 简洁、语法统一,且如今通过浏览器原生支持得到了大力推广。

      浏览器支持

      现代浏览器已经支持 ESModule,通过 <script type="module"> 标签加载 JavaScript 模块:
      这使得在前端开发中,我们可以直接利用原生的模块化特性,而无需借助工具进行转换。

      小结

      ESModule 提供了一个高效、标准化的模块化方案,通过 importexport 语法帮助开发者更好地组织代码、明确依赖关系,提升了代码的可维护性和优化潜力。它已经成为现代前端开发中不可或缺的技术之一。
      • 一套构建指令,使用Rollup打包(预配置的),把高度优化的静态资源用于生产环境

      为什么选择Vite

      📌
      这里我会结合一些自己开发中遇到的一些问题来描述一下为什么要选择Vite

      现实问题

      官方文档中提到,之前存在诸如如rollup(没用过)、webpack、Parcel(没用过)工具变迁,极大的改善了前端的开发效率,但是也会遇到一些问题(我这里没有完整的复制官网的文档,说一些自己的理解)
      我们这里只对webpack和vite来做为区别
      • webpack
        • webpack其实可以理解为,他在你编译的时候就把所有的模块、数据啊什么的全部都读取一遍,需要处理你的依赖关系,然后再利用自己的tree-shaking等等机制来打包和编译,而且随着你项目的增多,他每次都需要很久(项目越大越久),同时也会导致你每次HMR的时候,越来越久。可能你ctrl+s保存了,想看看效果,得等5s的时间(可能会更久,要看项目大小)因为每次他都要重新构建自己的依赖链。然后资源过多的时候还会出现爆栈👇类似于这种的报错
          如果电脑性能不太行的话,这个时候你可能就要:重启→等待编译→刷新浏览器→再点到你的业务页面总之,体验非常的糟糕(可能后面大版本更新以后会有所改善,但是我这里主要是看vite的,就不去做过多的介绍了)
          📌
          这里写一下怎么进行优化来减少这个问题
          1. 调整内存限定
          1. 进一步优化构建的过程
            1. 代码拆分:减少单个bundle的体积
            2. 使用缓存:合理利用打包插件提高打包效率
            3. 移除一些没用到的loader:检查一下是否有冗余配置,可能会导致额外的内存消耗
          什么是Bundle(捆绑文件)?
          • 名词解释:通常是指将多个js模块、资源以及他们之间的依赖关系通过打包工具(webpack,rollup)处理后合并成一个或者一组文件的过程及产物。
          • 性能优化:
            • 减少网络请求:将多个文件合并成一个文件,可以降低http请求的数量
            • 代码压缩和优化:在打包过程中可以对代码进行打包,tree-shaking等处理,减少文件体积,提高加载速度
      • vite
        • vite就是用原生esmodule和Rollup来提高自己的编译和打包速度,且越来越多 JavaScript 工具使用编译型语言编写。
          编译型:在程序运行前,通过编译器把源代码转换成机器码,如 C/C++、Go 非编译型(运行时):代码在运行时由解释器逐行解释执行,如 Python、JavaScript

      缓慢的服务器启动

      官方是这么说的:
      当冷启动开发服务器时,基于打包器的方式启动必须优先抓取并构建你的整个应用,然后才能提供服务。
      我的理解就是上面说的,webpack就是要把你所有的依赖都看一遍,然后你才能用
      但是vite改变了这个形式,他把模块修改成了依赖源码两类
      • 依赖 大多为在开发时不会变动的纯 JavaScript。一些较大的依赖(例如有上百个模块的组件库)处理的代价也很高。依赖也通常会存在多种模块化格式(例如 ESM 或者 CommonJS)。
        • Vite 将会使用 esbuild 预构建依赖。esbuild 使用 Go 编写,并且比以 JavaScript 编写的打包器预构建依赖快 10-100 倍。
      • 源码 通常包含一些并非直接是 JavaScript 的文件,需要转换(例如 JSX,CSS 或者 Vue/Svelte 组件),时常会被编辑。同时,并不是所有的源码都需要同时被加载(例如基于路由拆分的代码模块)。
        • Vite 以 原生 ESM 方式提供源码。这实际上是让浏览器接管了打包程序的部分工作:Vite 只需要在浏览器请求源码时进行转换并按需提供源码。根据情景动态导入代码,即只在当前屏幕上实际使用时才会被处理。
          notion image
      然后你就会在浏览器看到很多类似于这种的请求,然后当你看其他的时候页面的时候,也是会发送请求去获取的。

      缓慢的更新

      基于打包启动时,当源文件被修改后,重新构建整个包是低效的,原因显而易见:更新速度会随着应用体积的增加而线性下降。
      一些打包器的开发服务器将构建内容存入内存,这样它们只需要在文件更改时使模块图的一部分失活[1],但它也仍需要整个重新构建并重载页面。这样代价很高,并且重新加载页面会消除应用的当前状态,所以打包器支持了动态模块热替换(HMR):允许一个模块 “热替换” 它自己,而不会影响页面其余部分。这大大改进了开发体验 —— 然而,在实践中我们发现,即使采用了 HMR 模式,其热更新速度也会随着应用规模的增长而显著下降。
      在 Vite 中,HMR 是在原生 ESM 上执行的。当编辑一个文件时,Vite 只需要精确地使已编辑的模块与其最近的 HMR 边界之间的链失活[1](大多数时候只是模块本身),使得无论应用大小如何,HMR 始终能保持快速更新。
      Vite 同时利用 HTTP 头来加速整个页面的重新加载(再次让浏览器为我们做更多事情):源码模块的请求会根据 304 Not Modified 进行协商缓存,而依赖模块请求则会通过 Cache-Control: max-age=31536000,immutable 进行强缓存,因此一旦被缓存它们将不需要再次请求。
      这里就提到了一个问题,什么是协商缓存,什么是强缓存,正好昨天刚看了一下这个,嘻嘻
      通过协商缓存判断这个地方有没有更新,如果有更新了就返回,然后就是用返回的
       

      Loading...
      面试题分享

      面试题分享


      关于MCP

      关于MCP


      公告
      最近在看AI-sdk和vite相关内容,后续会继续整理