首页
/ Vite 项目哲学:精简核心、ESM 优先与原生工具链如何塑造 Vite 的设计决策

Vite 项目哲学:精简核心、ESM 优先与原生工具链如何塑造 Vite 的设计决策

2026-09-04 17:02:34作者:董灵辛Dennis

本文基于 Vite 官方文档 Project Philosophy 展开,系统梳理 Vite 项目层面的五条设计哲学:精简可扩展的核心、面向现代 Web 的取向、务实的性能策略、作为框架基础设施的定位,以及活跃生态协作机制。读完本文,你将理解这些哲学在 Vite 源码中的具体落点(插件体系、Oxc/Rolldown 转换管线、构建选项等),从而能够解释 Vite 的诸多 API 决策背后的原因,并在插件开发与框架搭建中做出与项目演进方向一致的技术选型。

一、哲学总览:五条原则构成 Vite 的决策框架

docs/guide/philosophy.md 将项目哲学归纳为五个部分,它们共同回答了“Vite 如何保持长期可维护”“Vite 为何坚持某些现代标准”“Vite 的性能投入取舍在哪里”“Vite 与框架生态的关系是什么”“生态演进如何治理”这五个问题:

哲学 核心主张
Lean Extendable Core 开箱即用支持最常见模式,但核心保持精简;通过强原语和 API 让插件去覆盖长尾场景
Pushing the Modern Web 源码只写 ESM、Worker 用 new Worker 语法、浏览器端禁止 Node.js 模块,以面向未来的 API 为先
A Pragmatic Approach to Performance 用 Oxc 与 Rolldown 等原生工具实现密集任务,其余部分保留在 JS 中以平衡速度与灵活性
Building Frameworks on Top of Vite 核心是框架无关的,但提供 SSR 原语、JS API 与插件机制,使 Vite 最适合作为 App 框架的底座
An Active Ecosystem 通过与框架/插件维护者、用户协作,在发布前用生态 CI 最小化回归

下面逐条结合仓库源码展开。

二、精简可扩展的核心:插件体系是首要抽象

官方文档的表述是:Vite 力求开箱即用支持构建 Web 应用的最常见模式,同时让核心保持精简、长期可维护;最好的方式不是把功能做进核心,而是提供足够强的原语和 API 让插件在其上构建。Vite 的插件系统基于 Rollup 插件 API 的超集(superset),并且其打包器 Rolldown 保持对 Rollup 插件接口的兼容,因此许多插件可以在 Vite 与纯 Rollup 项目之间通用。

在仓库中可以找到这一主张的直接证据:

  1. Vite 插件类型是 Rolldown 插件的超集packages/vite/src/node/plugin.ts 中定义:
export interface Plugin<A = any> extends RolldownPlugin<A> {

即 Vite 的 Plugin 在 Rolldown 插件接口之上做扩展(增加了 applyToEnvironment 等环境相关钩子)。这正是文档所说的“superset of Rollup's plugin API”在当前版本中的落地形态:由于 Rolldown 兼容 Rollup 插件接口,生态中大量基于 Rollup 写法的插件无需重写即可运行。

  1. 核心内置能力本身也是插件packages/vite/src/node/plugins/index.tsresolvePlugins 函数展示了完整的内部插件装配顺序:optimizedDepsPluginpreAliasPluginoxcResolvePlugincssPluginoxcPluginwasmHelperPluginwebWorkerPluginassetPluginbuildHtmlPlugindefinePlugin 等内置插件与用户插件(prePlugins / normalPlugins / postPlugins 三个插入点)在同一队列中排序执行。用户可以写一个 vite:asset 风格的自定义插件替换或增强对应行为——“核心精简、能力靠插件扩展”在架构上就是这么实现的。

  2. 同一能力可切换到原生实现。同一文件中的 applyToEnvironment 逻辑显示:当环境是 bundled 模式且 alias 不含自定义 resolver 时,Vite 会直接使用 Rolldown 原生的 viteAliasPlugin 替代基于 @rollup/plugin-alias 的 JS 实现;JSON 解析同理切换为 nativeJsonPlugin。这是“保持 JS 灵活性 + 密集任务走原生”这一哲学(见下节)在核心代码里的典型样本。

插件 API 的完整钩子文档见 Plugin API

三、推动现代 Web:三条明确的现代标准取向

Project Philosophy 明确列出 Vite 会用“有主见”(opinionated)的特性推动现代代码写法,具体包括三条,且新增功能会遵循同样的模式,即使这导致与某些旧式构建工具不兼容:

  • 源码只能用 ESM 书写,非 ESM 的依赖需要被预打包为 ESM 才能工作,机制详见 Dependency Pre-bundling
  • Web Worker 鼓励使用 new Worker 构造器语法,以贴近 Web 标准,见 Features - Web Workers
// 推荐的现代写法
const worker = new Worker(new URL('./worker.js', import.meta.url))

// 支持创建 module worker
const worker = new Worker(new URL('./worker.js', import.meta.url), {
  type: 'module',
})

文档同时说明:new URL() 必须直接出现在 new Worker() 声明内才会被识别为 worker,否则按静态资源 URL 处理;此外 ?worker / ?sharedworker 查询后缀导入仍是可用的替代方式(默认导出为自定义 worker 构造器,配合 &inline 可内联为 base64)。Worker 相关实现位于 packages/vite/src/node/plugins/worker.ts

  • Node.js 模块不能在浏览器中使用,浏览器端环境只做面向浏览器的模块解析。

这三条取向的共同点是:API 设计向 Web 平台标准(ESM、Worker 构造器、浏览器运行环境)靠拢,而不是向 Node.js 生态妥协。这解释了为什么 Vite 的许多 API(如 import.meta.url 系列用法)在 Node 语境下需要适配层。

四、务实的性能观:原生工具 + JS 管线的混合架构

文档指出:Vite 自起源起就聚焦性能,其 dev server 架构让 HMR 在项目规模增大时依然保持快速。关键策略是“混合架构”:用原生工具(Oxc 工具链与 Rolldown)承担密集任务,其余代码保持 JS 实现,以在速度和灵活性之间取得平衡;框架插件在需要时调用 Babel 编译用户代码;同时借助 Rolldown 对 Rollup 插件的兼容性保留庞大的插件生态。

4.1 混合架构在源码中的体现

  • Vite 8.x 的依赖清单直接反映了工具链底座packages/vite/package.json 中运行时依赖为 rolldown(~1.2.6)、lightningcsspicomatchpostcsstinyglobby;Node 版本要求为 ^20.19.0 || >=22.12.0(见 engines)。esbuild 已移至 peer/dev 依赖用于兼容场景,这印证了 Why Vite 中“统一工具链”(Rolldown + Oxc 取代 esbuild + Rollup 双管线)的演进事实。

  • TS/JSX 转换由 Oxc 原生完成packages/vite/src/node/plugins/oxc.ts 中的 transformWithOxc 直接调用 rolldown/utils 暴露的 transformSync(Rust 侧实现的同步转换),并按文件扩展名推导语言(cjs/mjsjscts/mtsts)。oxcPlugin同文件 L210)的默认过滤规则是 include: /\.(m?ts|[jt]sx)$/exclude: /\.js$/,即默认只转换 TS 与 JSX 文件,普通 JS 不走转换管线——这是“密集任务走原生、轻量路径保持低成本”的具体参数化体现。

  • bundled 环境整体交给 Rolldown 原生插件oxcPluginapplyToEnvironmentL277-L305)在环境为 isBundled 时返回 Rolldown 的 viteTransformPlugin,把转换完全下沉到 Rust 侧;非 bundled(unbundled dev)环境才走 JS 侧 transform 钩子。

  • 构建选项面向 Rolldown 开放packages/vite/src/node/build.tsbuild.rolldownOptions 用于向打包器注入原生选项(原 rollupOptions 字段已标记废弃),Vite 内部的 chunk、input、external 等配置与之合并后交给 Rolldown 执行。

4.2 Dev server 的 unbundled ESM 架构

性能哲学的另一半是 dev server 架构本身:Why Vite 解释了 Vite 把工作拆成两部分——依赖(很少变化)用原生工具预打包一次,源码(经常变化)通过原生 ESM 按需提供,浏览器只加载当前页面所需模块,Vite 在请求时逐个转换。这使得 dev server 启动几乎即时,编辑文件时 HMR 只更新对应模块而不需要整页重载或等待重新构建。

下图来自 Vite 官方文档 Why Vite,对比了两种 dev server 架构:

传统打包型 dev server 需要完整打包后才能提供服务

在传统打包型 dev server 中,整个应用必须先打包完毕才能被浏览器访问。

基于 ESM 的 dev server 按需提供模块

在基于 ESM 的 dev server 中,模块在浏览器请求时按需转换并提供——Vite 开发模式采用的正是这种方式。

需要说明的是,Why Vite 同时指出:unbundled ESM 在生产构建中并不高效(嵌套 import 带来额外网络往返),因此生产构建仍需打包优化;团队也在探索“full bundle mode”(开发阶段类似生产方式打包)以应对超大代码库的请求数压力。这正是哲学文档中“pragmatic(务实)”一词的注脚:性能取舍跟着场景走,而不是教条。

五、在 Vite 之上构建框架:Vite 最擅长的事

Project Philosophy 明确指出:尽管用户可以直接使用 Vite,但 Vite 最闪光的场景是作为创建框架的工具。具体支撑点包括:

  • 核心框架无关 + 各框架有打磨好的官方插件。仓库的 packages/create-vite 即为 React、Vue、Svelte、Preact、Solid、Qwik、Lit、vanilla 等框架提供了完整脚手架模板(如 template-react-tstemplate-vue-ts),每个模板对应的框架插件负责 JSX 编译、HMR 接线等工作——这正是“核心不感知框架、框架差异由插件补齐”的实例。
  • JS API 让框架作者复用 Vite 能力。通过 JS API,框架可以直接 createServer / build 并定制开发体验,而不是要求用户手写 vite.config
  • 内置 SSR 原语SSR 文档 描述的 ssrLoadModulessrTransform 等能力通常存在于更高层框架中,但 Vite 将其下沉为原语,供框架自行组合(仓库中 playground/ssrplayground/environment-react-ssr 等测试目录覆盖了大量 SSR 场景)。
  • Environment API 把“client/SSR 二选一”扩展为任意运行环境。文档“A Unified Toolchain / Where Vite is Heading”提到,Environment API 允许框架定义自定义环境(边缘运行时、service worker 等部署目标),各自拥有独立的模块解析与执行规则;源码中 applyToEnvironment(如前述 oxc 插件)与 packages/vite/src/node/environment.ts 即该模型的落点。
  • 与后端框架的良好搭配后端集成文档 展示了 Vite 与 Rails(vite_ruby)、Laravel 等后端框架前端资产管线的集成方式。

六、活跃生态:把生态健康作为发布流程的一部分

Project Philosophy 的最后一节描述了 Vite 的演进方式:框架/插件维护者、用户与 Vite 团队共同协作;项目一旦采用 Vite,官方鼓励积极参与核心开发;团队与生态中的主要项目紧密合作,借助 vite-ecosystem-ci 这类工具在选定的 PR 上运行主要 Vite 采用项目的 CI,从而在发布前获得“生态会如何反应”的清晰状态,目标是把回归修在影响用户之前,让项目能第一时间升级到新版本。

Why Vite 对这一机制做了补充:生态健康不是事后补救,而是发布流程本身的一部分——Rolldown 迁移期间正是“技术预览先行 + 生态 CI 提前发现兼容性问题 + 兼容层保留既有配置”三管齐下完成的。对开发者而言,可操作的推论是:

七、小结:五条哲学如何对应到你的日常开发

你面对的问题 对应哲学 仓库中的依据
为什么插件能拿到 Rolldown/Rollup 风格钩子 精简可扩展核心 plugin.tsPlugin extends RolldownPlugin
为什么只有 TS/JSX 走 Oxc 转换 务实的性能 oxc.ts 默认过滤规则
为什么 Worker 推荐 new Worker(new URL(...)) 推动现代 Web features.mdworker.ts
为什么生产构建仍要打包而非直接上 ESM 务实的性能 why.md 中 ESM 与打包分工说明
为什么框架都基于 Vite 而不是替代 Vite 构建框架的底座 JS APISSREnvironment API
升级 Vite 前如何评估生态风险 活跃生态 官方文档所述的 ecosystem CI 流程(philosophy.mdwhy.md

这套哲学的价值在于它解释了 API 的“为什么”:当你理解 Vite 选择“密集任务走 Rust、其余留 JS”“API 向 Web 标准靠拢、不向 Node 妥协”“核心只做原语、场景交给插件”之后,就能预判一个新 API 大概率长什么样,也能更准确地在插件开发、框架搭建与版本升级中做出与 Vite 演进方向一致的决策。

登录后查看全文
热门项目推荐
相关项目推荐

项目优选

收起
kernelkernel
deepin linux kernel
C
33
18
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.12 K
2.72 K
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
902
1.82 K
docsdocs
暂无描述
Markdown
888
5.78 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
854
1.34 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
527
590
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.51 K
1.01 K
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.33 K
1.45 K
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
540
384
flutter_flutterflutter_flutter
本仓库是 Flutter SDK 与 Flutter Engine 的 OpenHarmony 适配版本,由 CPF-Flutter 团队维护。开发者可使用熟悉的 Flutter 技术栈开发 OpenHarmony 应用,3.35.7 及以后的适配版本可基于本仓库源码构建支持 OpenHarmony 的 Flutter Engine。
Dart
1.17 K
341