# Vite

lastUpdated: 2023-8-08

官网:Vite中文网 (opens new window)

# 为什么说vite比webpack更快( vite对比webpack,优缺点在哪)

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

# vite工作原理

Vite (opens new window)是一种现代化的前端开发工具,其工作原理主要分为以下几个步骤:

  1. 基于ESM构建:Vite作为一款基于ESM的前端构建工具,通过ES模块提供的动态导入功能来实现快速的开发和构建。

  2. 零配置开发:Vite允许开发者在不需要任何配置的情况下启动一个服务器进行开发,通过对文件的即时编译和缓存,来提高开发效率。

  3. 基于浏览器原生的ESM加载:Vite将所有文件视为ES模块,并且在开发时会直接从源代码加载模块,而不是打包后的文件,从而可以避免打包的过程带来的性能损失。

  4. 按需编译和缓存:Vite会按需编译和缓存依赖项,只有当需要更新时才会进行重新编译,缓存让开发者可以忽略无关的代码变化。

  5. 插件化架构:Vite的插件化架构可以方便地扩展其功能,例如使用插件来处理CSS、处理图片、压缩源代码等等。

通过以上几个步骤,Vite实现了快速、高效的前端开发 (opens new window)和构建。

# vite和webpack的区别(两张图必背)

Vite 和 Webpack 都是现代化的前端构建工具,它们可以帮助开发者优化前端项目的构建和性能。虽然它们的目标是相似的,但它们在设计和实现方面有许多不同之处。

两者原理图

区别如下:

  1. 构建原理: Webpack 是一个静态模块打包器,通过对项目中的 JavaScript、CSS、图片等文件进行分析,生成对应的静态资源,并且可以通过一些插件和加载器来实现各种功能;Vite 则是一种基于浏览器原生 ES 模块解析的构建工具。

  2. 打包速度: Webpack 的打包速度相对较慢,Vite 的打包速度非常快。

  3. 配置难度: Webpack 的配置比较复杂,因为它需要通过各种插件和加载器来实现各种功能;Vite 的配置相对简单,它可以根据不同的开发场景自动配置相应的环境变量和配置选项。

  4. 插件和加载器: Webpack 有大量的插件和加载器可以使用,可以实现各种复杂的构建场景,例如代码分割、按需加载、CSS 预处理器等;Vite 的插件和加载器相对较少

  5. Vite是按需加载,webpack是全部加载: 在HMR(热更新)方面,当改动了一个模块后,vite仅需让浏览器重新请求该模块即可,不像webpack那样需要把该模块的相关依赖模块全部编译一次,效率更高。

  6. 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 服务就行,反正浏览器会自己去根据依赖关系去自己加载依赖。答案是不行的,为啥呢:

  1. 你代码是放在服务器的,过多的浏览器加载依赖肯定会引起更多的网络请求

  2. 为了在生产环境中获得最佳的加载性能,最好还是将代码进行 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 资源;

# Comment area