Vite 特性全解(含原理)- 小白入门级

228 阅读4分钟

Vite 介绍

vitejs.dev/guide/#over…

Vite(发音 /vit/,法语词汇,意为"快速")

  • 拥有快速冷启动和快速热更新的前端构建工具
  • 基于rollup 扩展的强大插件系统,便于扩展功能
  • 开发环境,基于esbuild 和 native es module 的高速开发服务器(dev server)
  • 生产环境,基于rollup 完成可兼容的资源打包

Vite 优点

  • 功能丰富,配置简单

  • 提供更棒的开发体验

    • 冷启动速度极快,800ms 左右 (ps: esbuild, native ES module, pre-bundle 提供了帮助)

      "冷启动"(Cold Start)通常指的是在执行构建过程时,首次运行或重新启动构建工具时所经历的初始阶段。

    • 模块热重载极快(ps: esbuild, native ES module 提供了帮助)

vite dev server 浅析

vitejs.dev/guide/why.h…

对比传统 webpack,rollup 等打包工具,vite 在开发体验上的提升无疑是显著。结合vite 官方文档和原理总结其提升原因如下

  • esbuild
  • pre-bundle
  • native es module

esbuild

vitejs.dev/guide/featu…

.jsx 和 .tsx 文件同样开箱即用。JSX 的转译同样是通过 esbuild。

vitejs.dev/guide/featu…

Vite 使用 esbuild 将 TypeScript 转译到 JavaScript,约是 tsc 速度的 20~30 倍,同时 HMR 更新反映到浏览器的时间小于 50ms。

esbuild.github.io/api/#transf…

esbuild 启动的 vite 开发服务器(dev server),其运行速度显著优于基于Javascript 编写的构建工具。

同时,esbuildvite 提供了 .tsx , .jsx ,tsx 文件的转译支持,正因此,其代码转译文件热更新的速度也相对较快

native es module 原生ES模块

vitejs.dev/guide/featu…

Vite 放弃了传统的将模块打包生成bundle文件的方式,它利用浏览器支持原生ES模块的特性,直接向浏览器传送ES模块文件,将模块的解析和编译推迟到浏览器中进行,从而提供更快的开发体验。

传统bundle方式 image.png

原生ES模块方式 image.png

具体的工作原理如下:

  1. 开发阶段:当你启动 Vite 时,它会创建一个开发服务器,该服务器会拦截浏览器对模块的请求。当浏览器请求一个模块时,Vite 会根据请求的模块路径,动态返回模块文件给浏览器。
  1. 浏览器支持:现代浏览器原生支持 ES 模块,这意味着浏览器可以直接加载和执行模块文件,无需进行额外的编译和转换。因此,Vite 可以将模块的解析和编译工作交给浏览器来处理,从而避免了传统打包工具中繁重的构建过程。
  1. 模块热更新:Vite 还利用了浏览器原生的模块热更新功能。当你修改了一个模块的代码后,Vite 会通知浏览器重新请求该模块,并将更新后的代码传递给浏览器。浏览器会只重新加载修改的模块,从而实现即时的模块热更新,无需刷新整个页面。

pre-bundle 预构建

Vite npm 依赖解析和预构建处理

Vite 依赖预构建

Vite 预构建源码解读 2021版

Vite 预构建源码解读 2023版

预构建的效果:提高冷启动速度和模块热更新速度

执行时机:首次启动 Vite 本地开发服务器时,Vite 会自动进行依赖预构建

预构建原因和作用:

  1. 兼容 CommonJS 和 UMD 类型的代码

在开发阶段中,Vite 的开发服务器将所有代码视为原生 ES 模块。因此,Vite 必须先将以 CommonJS 或 UMD 形式提供的依赖项转换为 ES 模块。

  1. 性能提升

Vite将那些具有许多内部模块的 ESM 依赖项转换为单个模块。

例如,lodash-es 有超过 600 个内置模块!当我们执行

import { debounce } from 'lodash-es' 时,

浏览器同时发出 600 多个 HTTP 请求!即使服务器能够轻松处理它们,但大量请求会导致浏览器端的网络拥塞,使页面加载变得明显缓慢。

不预构建 lodash-es时,Http请求量超过 600 个

{
 optimizeDeps: {
  exclude: ['lodash','lodash-es']
 }
}
  1. 浏览器的原生ES模块,不支持解析如下裸模块(bare module)导入
 import { someMethod } from 'my-dep' 
    

需要将裸模块导入的路径变更浏览器支持识别的路径,例如

/node_modules/.vite/deps/my-dep.js?v=f3sf2ebd

总结:

利用预构建,Vite避免了传统的解析依赖,构建打包生成bundle的过程,让依赖也能像常见的模块一样,在页面按需引用。