为何选择 Vite
随着 Web 应用的规模和复杂度不断提升,构建这些应用的工具也面临着巨大挑战。大型项目的开发者常会遇到开发服务器启动缓慢、热更新迟钝以及生产环境构建耗时长等问题。虽然每一代构建工具都在前代基础上有所改进,但这些痛点依然存在。
Vite 的诞生正是为了解决这些问题。它没有选择在现有的构建方法上进行渐进式改进,而是重新思考了开发环境下的代码服务方式。自那时起,Vite 历经多个重大版本的更迭,每一次都适应了生态系统中涌现的新能力:从利用浏览器原生 ES 模块,到采用完全由 Rust 驱动的工具链。
如今,Vite 为许多框架和工具提供了动力。它的架构设计旨在与 Web 平台共同演进,而非锁定在某种特定的方法上,这使其成为一个可以长期依赖的坚实基础。
起源
Vite 最初创建时,浏览器刚开始广泛支持 ES 模块 (ESM)。这是一种无需预先使用打包工具将所有文件合并,即可直接加载 JavaScript 文件的方式。传统的构建工具(通常称为打包器)在浏览器能够显示任何内容之前,需要先处理整个应用。应用规模越大,等待时间就越长。
Vite 采用了不同的策略,将工作分为两部分:
- 依赖项(那些几乎不会改变的库)会使用快速的原生工具进行预打包,因此它们可以瞬间就绪。
- 源码(那些频繁变更的应用代码)则通过原生 ESM 按需提供。浏览器仅加载当前页面所需的内容,Vite 会在请求时对每个文件进行转换。
这意味着开发服务器的启动速度几乎是瞬间完成的,无论应用规模大小。当你编辑一个文件时,Vite 会利用原生 ESM 实现热模块替换 (HMR),仅在浏览器中更新该模块,而无需重新加载整个页面或等待重新构建。
在基于打包器的开发服务器中,整个应用必须在服务前先完成打包。
在基于 ESM 的开发服务器中,模块是在浏览器请求时按需提供的。
Vite 并非第一个探索这种方法的工具。Snowpack 开创了非打包式的开发方式,并启发了 Vite 的依赖预打包机制。WMR(由 Preact 团队开发)启发了适用于开发和生产环境的通用插件 API。@web/dev-server 则影响了 Vite 1.0 的服务器架构。Vite 在这些思想的基础上,进一步将其发扬光大。
尽管非打包式的 ESM 在开发过程中表现良好,但在生产环境中直接使用却效率低下,因为嵌套导入会产生过多的网络往返次数。这正是为什么打包在生产环境中依然必要,以实现更优的构建结果。
与生态系统共同成长
随着 Vite 的成熟,各类框架开始将其作为构建层。基于 Rollup 惯例的插件 API,使得框架无需绕过 Vite 的内部结构即可实现自然集成。Nuxt、SvelteKit、Astro、React Router、Analog、SolidStart 等框架都选择了 Vite 作为其底层基础。Vitest 和 Storybook 等工具也构建于此,扩展了 Vite 在应用打包之外的应用场景。像 Laravel 和 Ruby on Rails 这样的后端框架也集成了 Vite,用于管理其前端资源管道。
这种增长并非单向的。生态系统塑造了 Vite,正如 Vite 塑造了生态系统。Vite 团队运行着 vite-ecosystem-ci,针对每一次 Vite 的代码变更对主流生态项目进行测试。生态系统的健康不是事后补救,而是发布流程的一部分。
统一的工具链
Vite 最初在底层依赖两个独立的工具:用于开发环境快速编译的 esbuild,以及用于生产环境深度优化的 Rollup。这虽然可行,但维护两条流水线导致了不一致性:不同的转换行为、两套独立的插件系统,以及为了保持对齐而不得不编写的粘合代码。
Rolldown 的出现正是为了将两者统一为一个打包器:它使用 Rust 编写以实现原生速度,并兼容生态系统已经依赖的相同插件 API。它利用 Oxc 进行解析、转换和压缩。这为 Vite 提供了一个端到端的工具链,使得构建工具、打包器和编译器可以共同维护并作为一个整体演进。
结果就是从开发到生产拥有一套连贯的流水线。迁移过程非常谨慎:首先发布了技术预览版,以便早期采用者验证变更;通过生态系统 CI 及早捕获兼容性问题;并通过兼容层保留了现有的配置。
Vite 的未来方向
Vite 的架构将持续演进,以下几个方面正在塑造其未来:
全打包模式:Vite 创建时,非打包式的 ESM 是最佳权衡方案,因为当时没有工具既能满足极速,又具备开发环境所需的 HMR 和插件能力。Rolldown 改变了这一现状。由于极其庞大的代码库可能会因大量的非打包网络请求导致页面加载缓慢,团队正在探索一种模式,让开发服务器像生产环境一样对代码进行打包,从而减少网络开销。
环境 API:不再将“客户端”和“SSR”视为仅有的两个构建目标,环境 API (Environment API) 允许框架定义自定义环境(如边缘运行时、Service Worker 等其他部署目标),每个环境都有各自的模块解析和执行规则。随着代码运行的位置和方式日益多样化,Vite 的模型也将随之扩展。
与 JavaScript 同步演进:随着 Oxc 和 Rolldown 与 Vite 的紧密协作,新的语言特性和标准可以快速在整个工具链中采用,无需等待上游依赖的更新。
Vite 的目标不是成为终极工具,而是成为一个能够与 Web 平台以及构建于其上的开发者们一同持续演进的工具。
