# Vite
lastUpdated: 2023-8-08
# 为什么说vite比webpack更快( vite对比webpack,优缺点在哪)
- webpack会先打包,然后启动开发服务器,请求服务器时直接给予打包结果。
- vite是直接启动开发服务器,请求哪个模块再对该模块进行实时编译。
- vite在启动的时候不需要打包,意味着不需要分析模块的依赖、不需要编译,因此启动速度非常快。
- 当浏览器请求某个模块时,再根据需要对模块内容进行编译。这种按需动态编译的方式,极大的缩减了编译时间,项目越复杂、模块越多,vite的优势越明显。
- 在HMR方面,当改动了一个模块后,仅需让浏览器重新请求该模块即可,不像webpack那样需要把该模块的相关依赖模块全部编译一次,效率更高。
- 当需要打包到生产环境时,vite使用传统的rollup进行打包,因此,vite的主要优势在开发阶段。另外,由于vite利用的是ES Module,因此在代码中不可以使用CommonJS

# vite工作原理
Vite (opens new window)是一种现代化的前端开发工具,其工作原理主要分为以下几个步骤:
基于ESM构建:Vite作为一款基于ESM的前端构建工具,通过ES模块提供的动态导入功能来实现快速的开发和构建。
零配置开发:Vite允许开发者在不需要任何配置的情况下启动一个服务器进行开发,通过对文件的即时编译和缓存,来提高开发效率。
基于浏览器原生的ESM加载:Vite将所有文件视为ES模块,并且在开发时会直接从源代码加载模块,而不是打包后的文件,从而可以避免打包的过程带来的性能损失。
按需编译和缓存:Vite会按需编译和缓存依赖项,只有当需要更新时才会进行重新编译,缓存让开发者可以忽略无关的代码变化。
插件化架构:Vite的插件化架构可以方便地扩展其功能,例如使用插件来处理CSS、处理图片、压缩源代码等等。
通过以上几个步骤,Vite实现了快速、高效的前端开发 (opens new window)和构建。
# vite和webpack的区别(两张图必背)
Vite 和 Webpack 都是现代化的前端构建工具,它们可以帮助开发者优化前端项目的构建和性能。虽然它们的目标是相似的,但它们在设计和实现方面有许多不同之处。
两者原理图


区别如下:
构建原理: Webpack 是一个静态模块打包器,通过对项目中的 JavaScript、CSS、图片等文件进行分析,生成对应的静态资源,并且可以通过一些插件和加载器来实现各种功能;Vite 则是一种基于浏览器原生 ES 模块解析的构建工具。
打包速度: Webpack 的打包速度相对较慢,Vite 的打包速度非常快。
配置难度: Webpack 的配置比较复杂,因为它需要通过各种插件和加载器来实现各种功能;Vite 的配置相对简单,它可以根据不同的开发场景自动配置相应的环境变量和配置选项。
插件和加载器: Webpack 有大量的插件和加载器可以使用,可以实现各种复杂的构建场景,例如代码分割、按需加载、CSS 预处理器等;Vite 的插件和加载器相对较少
Vite是按需加载,webpack是全部加载: 在HMR(热更新)方面,当改动了一个模块后,vite仅需让浏览器重新请求该模块即可,不像webpack那样需要把该模块的相关依赖模块全部编译一次,效率更高。
webpack是先打包再启动开发服务器,vite是直接启动开发服务器,然后按需编译依赖文件 由于vite在启动的时候不需要打包,也就意味着不需要分析模块的依赖、不需要编译,因此启动速度非常快。当浏览器请求某个模块时,再根据需要对模块内容进行编译,这种按需动态编译的方式,极大的缩减了编译时间。
# 什么是vite
vite是新一代的前端构建工具
# vite核心原理
Vite其核心原理是利用浏览器现在已经支持ES6的import,碰见import就会发送一个HTTP请求去加载文件。
Vite整个过程中没有对文件进行打包编译,做到了真正的按需加载,所以其运行速度比原始的webpack开发编译速度快出许多! 特点:
快速的冷启动:基于Esbuild的依赖进行预编译优化 (Esbuild 打包速度太快了,比类似的工具快10~100倍 )
增加缓存策略:源码模块使用协商缓存,依赖模块使用强缓;因此一旦被缓存它们将不需要再次请求。
HMR(热更新):当修改代码时,HMR 能够在不刷新页面的情况下,把页面中发生变化的模块,替换成新的模块,同时不影响其他模块的正常运作 聊聊 ESM、Bundle 、Bundleless 、Vite 、Snowpack - 大前端 - SegmentFault 思否
基于 Rollup 打包:生产环境下由于esbuild对css和代码分割并使用Rollup进行打包;
高效的热更新:基于ESM实现,同时利用HTTP头来加速整个页面的重新加载,
# Vite 冷启动为什么快
Vite 运行 Dev 命令后只做了两件事情,一是启动了本地服务器并注册了一些中间件;二是使用 ESbuild 预构建模块。
生产环境
刚刚咱们说的都是 开发环境 ,也说了, Vite 在是直接把转化后的 es module 的JavaScript,扔给浏览器,让浏览器根据依赖关系,自己去加载依赖。
那有人就会说了,那放到 生产环境 时,是不是可以不打包,直接在开个 Vite 服务就行,反正浏览器会自己去根据依赖关系去自己加载依赖。答案是不行的,为啥呢:
你代码是放在服务器的,过多的浏览器加载依赖肯定会引起更多的网络请求
为了在生产环境中获得最佳的加载性能,最好还是将代码进行 tree-shaking、懒加载和 chunk 分割、CSS处理,这些优化操作,目前 esbuild 还不怎么完善
缺点:
首屏和懒加载的性能下降 为什么?
生态不如webpack,webpack的loader和plugin非常的丰富;
生产环境使用 rollup 打包可能会造成开发环境与生产环境的不一致。因为打包方式不一样,生产的打包方式是rollup 打包,开发打包是直接把转化后的 es module 的JavaScript,扔给浏览器,让浏览器根据依赖关系,自己去加载依赖
目前 Vite 还是使用的 es module 模块不能直接使用生产环境(兼容性问题,如果你的项目不需要兼容 IE11 等低版本的浏览器,自然是可以使用的)
怎么在vite中引入图片资源?
vite 是如何处理vue单文件组件的?
怎么在vite中使用css预处理器?
vite支持哪些类型的模块加载器
如何在生产环境中使用vite
在使用vite时遇到的最大挑战是什么?你是怎么解决的?
使用过哪些vite的插件
vite是如何处理es模块的循环引用问题?
基于ESM的Dev server
- 在Vite出来之前,传统的打包工具如Webpack是先解析依赖、打包构建再启动开发服务器,Dev Server 必须等待所有模块构建完成后才能启动,当我们修改了 bundle模块中的一个子模块, 整个 bundle 文件都会重新打包然后输出。项目应用越大,启动时间越长。
- 而Vite利用浏览器对ESM的支持,当 import 模块时,浏览器就会下载被导入的模块。先启动开发服务器,当代码执行到模块加载时再请求对应模块的文件,本质上实现了动态加载。
# 基于ESM的HRM热更新
所有的 HMR 原理:
目前所有的打包工具实现热更新的思路都大同小异:主要是通过WebSocket创建浏览器和服务器的通信监听文件的改变,当文件被修改时,服务端发送消息通知客户端修改相应的代码,客户端对应不同的文件进行不同的操作的更新。
Vite 的表现:
- Vite 监听文件系统的变更,只用对发生变更的模块重新加载,这样HMR 更新速度就不会因为应用体积的增加而变慢
- 而 Webpack 还要经历一次打包构建。
- 所以 HMR 场景下,Vite 表现也要好于 Webpack。
# 基于Esbuild的依赖预编译优化
Vite预编译之后,将文件缓存在node_modules/.vite/文件夹下
# 为什么需要预编译&预构建
- 支持 非ESM 格式的依赖包:Vite是基于浏览器原生支持ESM的能力实现的,因此必须将commonJs的文件提前处理,转化成 ESM 模块并缓存入 node_modules/.vite
- 减少模块和请求数量:Vite 将有许多内部模块的 ESM 依赖关系转换为单个模块,以提高后续页面加载性能。 如果不使用esbuild进行预构建,浏览器每检测到一个import语句就会向服务器发送一个请求,如果一个三方包被分割成很多的文件,这样就会发送很多请求,会触发浏览器并发请求限制;
# 为什么用Esbuild
Esbuild 打包速度太快了,比类似的工具快10~100倍,
文档:esbuild - 极速 JavaScript 打包器 | esbuild中文文档 | esbuild中文网 (opens new window)
# Esbuild为什么为么快
- Esbuild 使用 Go 语言编写,可以直接被转化为机器语言,在启动时直接执行;
- 而其余大多数的打包工具基于 JS 实现,是解释型语言,需要边运行边解释;
- JS 本质上是单线程语言,GO语言天生具有多线程的优势,充分利用 CPU 资源;