一文搞懂:极速前端构建神器Vite

简介

Vite(法语意为 "快速的",发音 /vit/,发音同 "veet")是一种新型前端构建工具,能够显著提升前端开发体验。它主要由两部分组成:

Vite 是一种具有明确建议的工具,具备合理的默认设置。您可以在 功能指南 中了解 Vite 的各种可能性。通过 插件,Vite 支持与其他框架或工具的集成。如有需要,您可以通过 配置部分 自定义适应你的项目。

Vite 还提供了强大的扩展性,可通过其 插件 API 和 JavaScript API 进行扩展,并提供完整的类型支持。

你可以在 为什么选 Vite 部分深入了解该项目的设计理念。

浏览器支持

在开发过程中,Vite 假设使用的是现代浏览器。这意味着该浏览器支持大多数最新的 JavaScript 和 CSS 功能。因此,Vite 将 esnext 设置为转换目标。这可以防止语法降低,使 Vite 能够尽可能接近原始源代码提供模块。Vite 会注入一些运行时代码以使开发服务器正常工作。这些代码使用了 Baseline 中包含的功能,该功能在每个主要版本发布时(此主要版本为 2025-05-01)新增。

对于生产环境构建,Vite 默认以 Baseline 广泛可用的浏览器为目标平台。这些浏览器至少发布于两年半之前。您可以通过配置降低目标浏览器版本。此外,可以通过官方 @vitejs/plugin-legacy 支持旧版浏览器。更多详情,请参阅 构建生产环境 部分。

在线试用 Vite

你可以通过 StackBlitz 在线试用 vite。它直接在浏览器中运行基于 Vite 的构建,因此它与本地开发几乎无差别,同时无需在你的机器上安装任何东西。你可以浏览 vite.new/{template} 来选择你要使用的框架。

目前支持的模板预设如下:

JavaScriptTypeScript
vanillavanilla-ts
vuevue-ts
reactreact-ts
preactpreact-ts
litlit-ts
sveltesvelte-ts
solidsolid-ts
qwikqwik-ts

搭建第一个 Vite 项目

npm:npm create vite@latest
yarn:yarn create vite
pnpm:pnpm create vite
bun:bun create vite
deno:deno init --npm vite

然后按照提示操作即可!

兼容性注意

Vite 需要 Node.js 版本 20.19+, 22.12+。然而,有些模板需要依赖更高的 Node 版本才能正常运行,当你的包管理器发出警告时,请注意升级你的 Node 版本。

你还可以通过附加的命令行选项直接指定项目名称和你想要使用的模板。例如,要构建一个 Vite + Vue 项目,运行:

# npm 7+,需要添加额外的 --:
npm create vite@latest my-vue-app -- --template vue
yarn create vite my-vue-app --template vue
pnpm create vite my-vue-app --template vue
bun create vite my-vue-app --template vue
deno init --npm vite my-vue-app --template vue

查看 create-vite 以获取每个模板的更多细节:vanillavanilla-tsvuevue-tsreactreact-tsreact-swcreact-swc-tspreactpreact-tslitlit-tssveltesvelte-tssolidsolid-tsqwikqwik-ts

你可以使用 . 作为项目名称,在当前目录中创建项目脚手架。

社区模板

create-vite 是一个快速生成主流框架基础模板的工具。查看 Awesome Vite 仓库的 社区维护模板,里面包含各种工具和不同框架的模板。

对于一个 https://github.com/user/project 中的模板,可以尝试使用 https://github.stackblitz.com/user/project(即在项目 URL 的 github 后添加 .stackblitz)。

你也可以用如 degit 之类的工具,使用社区模版来搭建项目。假设项目在 GitHub 上并使用 main 作为默认分支,可以使用以下命令创建本地副本:

npx degit user/project#main my-project
cd my-project

npm install
npm run dev

手动安装

在你的项目中,可以用以下方法来安装 vite 命令行工具:

npm install -D vite
yarn add -D vite
pnpm add -D vite
bun add -D vite
deno add -D npm:vite

并创建一个像这样的 index.html 文件:

<p>Hello Vite!</p>

然后在终端上运行相应的命令:

npx vite
yarn vite
pnpm vite
bunx vite
deno run -A npm:vite

之后就可以在 http://localhost:5173 上访问 index.html

index.html 与项目根目录

你可能已经注意到,在一个 Vite 项目中,index.html 在项目最外层而不是在 public 文件夹内。这是有意而为之的:在开发期间 Vite 是一个服务器,而 index.html 是该 Vite 项目的入口文件。

Vite 将 index.html 视为源码和模块图的一部分。Vite 解析 <script type="module" src="..."> ,这个标签指向你的 JavaScript 源码。甚至内联引入 JavaScript 的 <script type="module"> 和引用 CSS 的 <link href> 也能利用 Vite 特有的功能被解析。另外,index.html 中的 URL 将被自动转换,因此不再需要 %PUBLIC_URL% 占位符了。

与静态 HTTP 服务器类似,Vite 也有 “根目录” 的概念,即服务文件的位置,在接下来的文档中你将看到它会以 <root> 代称。源码中的绝对 URL 路径将以项目的 “根” 作为基础来解析,因此你可以像在普通的静态文件服务器上一样编写代码(并且功能更强大!)。Vite 还能够处理依赖关系,解析处于根目录外的文件位置,这使得它即使在基于 monorepo 的方案中也十分有用。

Vite 也支持多个 .html 作入口点的 多页面应用模式

指定替代根目录

执行 vite 命令会以当前工作目录作为根目录启动开发服务器。你也可以通过 vite serve some/sub/dir 来指定一个不同的根目录。 需要注意的是,Vite 也会在项目的根目录中寻找 它的配置文件(即 vite.config.js),所以如果更改了根目录,你需要将配置文件一起移动过去。

命令行接口

在安装了 Vite 的项目中,可以在 npm scripts 中使用 vite 可执行文件,或者直接使用 npx vite 运行它。下面是通过脚手架创建的 Vite 项目中默认的 npm scripts:

package.json

{
  "scripts": {
    "dev": "vite", // 启动开发服务器,别名:`vite dev`,`vite serve`
    "build": "vite build", // 为生产环境构建产物
    "preview": "vite preview" // 本地预览生产构建产物
  }
}

可以指定额外的命令行选项,如 --port 或 --open。运行 npx vite --help 获得完整的命令行选项列表。

使用未发布的功能

如果你迫不及待想要体验最新的功能,可以使用 https://pkg.pr.new 安装特定的 Vite 提交:

npm install -D https://pkg.pr.new/vite@SHA
yarn add -D https://pkg.pr.new/vite@SHA
pnpm add -D https://pkg.pr.new/vite@SHA
bun add -D https://pkg.pr.new/vite@SHA

将 SHA 替换为 Vite 的提交 SHA。请注意,仅最近一个月的提交有效,旧版本提交的构建产物会被清除。

或者,你可以克隆 Vite 代码仓库 到本地,自行构建并建立软链接(需安装 pnpm):

git clone https://github.com/vitejs/vite.git
cd vite
pnpm install
cd packages/vite
pnpm run build
pnpm link --global # 在这一步中可使用你喜欢的包管理器

然后,回到你的 Vite 项目并运行 pnpm link --global vite(或者使用你的其他包管理工具来全局链接 vite)。重新启动开发服务器来体验新功能吧!

处理依赖中的 Vite 版本

若需替换依赖链中传递使用的 Vite 版本(Transitive Dependencies),应使用 npm overrides 或 pnpm overrides

为什么选 Vite

现实问题

在浏览器支持 ES 模块之前,JavaScript 并没有提供原生机制让开发者以模块化的方式进行开发。这也正是我们对 “打包” 这个概念熟悉的原因:使用工具抓取、处理并将我们的源码模块串联成可以在浏览器中运行的文件。

时过境迁,我们见证了诸如 webpackRollup 和 Parcel 等工具的变迁,它们极大地改善了前端开发者的开发体验。

然而,当我们开始构建越来越大型的应用时,需要处理的 JavaScript 代码量也呈指数级增长。包含数千个模块的大型项目相当普遍。基于 JavaScript 开发的工具就会开始遇到性能瓶颈:通常需要很长时间(甚至是几分钟!)才能启动开发服务器,即使使用模块热替换(HMR),文件修改后的效果也需要几秒钟才能在浏览器中反映出来。如此循环往复,迟钝的反馈会极大地影响开发者的开发效率和幸福感。

Vite 旨在利用生态系统中的新进展解决上述问题:浏览器开始原生支持 ES 模块,且越来越多 JavaScript 工具使用编译型语言编写。

缓慢的服务器启动

当冷启动开发服务器时,基于打包器的方式启动必须优先抓取并构建你的整个应用,然后才能提供服务。

Vite 通过在一开始将应用中的模块区分为 依赖 和 源码 两类,改进了开发服务器启动时间。

  • 依赖 大多为在开发时不会变动的纯 JavaScript。一些较大的依赖(例如有上百个模块的组件库)处理的代价也很高。依赖也通常会存在多种模块化格式(例如 ESM 或者 CommonJS)。

    Vite 将会使用 esbuild 预构建依赖。esbuild 使用 Go 编写,并且比以 JavaScript 编写的打包器预构建依赖快 10-100 倍。

  • 源码 通常包含一些并非直接是 JavaScript 的文件,需要转换(例如 JSX,CSS 或者 Vue/Svelte 组件),时常会被编辑。同时,并不是所有的源码都需要同时被加载(例如基于路由拆分的代码模块)。

    Vite 以 原生 ESM 方式提供源码。这实际上是让浏览器接管了打包程序的部分工作:Vite 只需要在浏览器请求源码时进行转换并按需提供源码。根据情景动态导入代码,即只在当前屏幕上实际使用时才会被处理。

缓慢的更新

基于打包启动时,当源文件被修改后,重新构建整个包是低效的,原因显而易见:更新速度会随着应用体积的增加而线性下降。

一些打包器的开发服务器将构建内容存入内存,这样它们只需要在文件更改时使模块图的一部分失活,但它也仍需要整个重新构建并重载页面。这样代价很高,并且重新加载页面会消除应用的当前状态,所以打包器支持了动态模块热替换(HMR):允许一个模块 “热替换” 它自己,而不会影响页面其余部分。这大大改进了开发体验 —— 然而,在实践中我们发现,即使采用了 HMR 模式,其热更新速度也会随着应用规模的增长而显著下降。

在 Vite 中,HMR 是在原生 ESM 上执行的。当编辑一个文件时,Vite 只需要精确地使已编辑的模块与其最近的 HMR 边界之间的链失活(大多数时候只是模块本身),使得无论应用大小如何,HMR 始终能保持快速更新。

Vite 同时利用 HTTP 头来加速整个页面的重新加载(再次让浏览器为我们做更多事情):源码模块的请求会根据 304 Not Modified 进行协商缓存,而依赖模块请求则会通过 Cache-Control: max-age=31536000,immutable 进行强缓存,因此一旦被缓存它们将不需要再次请求。

一旦你体验到 Vite 的神速,你可能再也不想回到曾经的打包开发方式了。

为什么生产环境仍需打包

尽管原生 ESM 现在得到了广泛支持,但由于嵌套导入会导致额外的网络往返,在生产环境中发布未打包的 ESM 仍然效率低下(即使使用 HTTP/2)。为了在生产环境中获得最佳的加载性能,最好还是将代码进行 tree-shaking、懒加载和 chunk 分割(以获得更好的缓存)。

要确保开发服务器和生产环境构建之间的最优输出和行为一致并不容易。所以 Vite 附带了一套 构建优化 的 构建命令,开箱即用。

为何不用 ESBuild 打包?

虽然 Vite 利用 esbuild 在开发中预打包一些依赖,但 Vite 不会在生产构建中使用 esbuild 作为打包工具。

Vite 目前的插件 API 与使用 esbuild 作为打包器并不兼容。尽管 esbuild 速度更快,但 Vite 采用了 Rollup 灵活的插件 API 和基础建设,这对 Vite 在生态中的成功起到了重要作用。目前来看,我们认为 Rollup 提供了更好的性能与灵活性方面的权衡。

Rollup 已经开始着手改进性能,在 v4 中将其解析器切换到 SWC。同时还有一个正在进行中的工作,即构建一个名为 Rolldown 的 Rust 版本的 Rollup。一旦 Rolldown 准备就绪,它就可以在 Vite 中取代 Rollup 和 esbuild,显著提高构建性能,并消除开发和构建之间的不一致性。你可以观看 Evan You 在 ViteConf 2023 的主题演讲 了解更多细节。

Vite 与其他免打包构建工具的关系是什么?

Preact 团队的 WMR 旨在提供类似的功能集。Vite 用于开发和构建的通用 Rollup 插件 API 就是受其启发。WMR 已经不再维护。Preact 团队现在推荐使用 Vite 和 @preactjs/preset-vite

Snowpack 也是一个免打包的原生 ESM 开发服务器,与 Vite 的职责非常相似。Vite 的依赖预打包也受到了 Snowpack v1(现在是 esinstall)的启发。Snowpack 已经不再维护。Snowpack 团队现在正在研究由 Vite 驱动的静态网站构建器 Astro

@web/dev-server(以前是 es-dev-server)是一个伟大的项目,Vite 1.0 的基于 Koa 的服务器设置就是受其启发。@web 这个项目正在积极维护,并包含许多其他优秀的工具,这些工具也可能对 Vite 用户有所帮助。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

by__csdn

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值