编程 10,000 个组件启动快 15x:Vite 8.1 的 bundled dev 模式怎么开,以及哪里会踩坑

2026-09-16 00:04:39

10,000 个组件启动快 15x:Vite 8.1 的 bundled dev 模式怎么开,以及哪里会踩坑

Vite 8.1 于 2026-06-23 发布,带来了实验性的 Bundled Dev Mode。这个模式此前叫 Full Bundle Mode。Vite 8 在 2026 年 3 月用 Rolldown 统一了打包器,目前周下载 41.6M。

  • 官方公告:
  • 设计文档与路线图:
  • Phase 1 反馈:
  • Rolldown:
  • Vite 8 发布:

为什么 dev 也要打包

Vite 一直以非打包 dev server 著称:每个模块单独请求。项目规模上来之后,这个策略在开发期开始拖后腿——模块逐个 fetch,浏览器要处理大量请求,启动和刷新开销随之上升。大应用里尤其明显,开发者挂在网络代理后面时更严重。

Bundled Dev Mode 的做法是:不只生产环境出 bundle,开发期也出。目标三条:

  • 大应用也能快速启动
  • 刷新时减少网络开销
  • HMR 仍然建立在 ESM output 之上,保持高效

实测数字

官方用 10,000 个 React 组件的应用做初始测试:

  • 启动约 15x
  • 全量刷新约 10x
  • HMR 与应用规模无关,保持即时

真实应用上收益类似。Linear 团队的数据:冷启动渲染快最多 3x,全量刷新快约 40%,网络请求数少 10x

Phase 1 反馈里有一个小应用案例:在 Lovable 上开 experimental.bundledDev,经 preview 代理后的启动请求数从 34 降到 4。

开启方式

命令行:

vite --experimental-bundle

或在 vite.config.js 里:

import { defineConfig } from 'vite'

export default defineConfig({
experimental: {
bundledDev: true,
},
})

lazy bundling:启动时只编当前页面需要的模块

dev server 启动时不会打包整个应用。默认行为是 lazy bundling:只打包当前页面实际请求所需的模块,其余模块在被 import 时按需编译。这样大应用启动不被阻塞;如果一次性打包全应用,就等于把 Vite 非打包 dev server 本来想避开的慢冷启动又请回来了。

这个行为默认开启,不需要配置。一般也不用关,调试时可以通过 build.rolldownOptions.experimental.devMode.lazy 关闭。

当前边界

这一版聚焦浏览器侧、基础插件和主要功能。第三方插件可能不兼容,官方预期不是所有插件都能工作;一些小功能也可能不生效。SSR 相关功能不可用——前提是你的应用没有用到 Vite 的 SSR 能力,且第三方插件兼容。

experimental.bundledDev 在 Vite 8 类型定义里标了 @experimental,官方措辞是 highly experimental,API 可能随 patch 变化。

插件作者要注意的具体问题

  • ViteDevServer.waitForRequestsIdle 在 full bundle 模式下不工作,也没有意义。
  • 依赖文件结构被保留的插件,需要为 full bundle 模式重写 URL。Vite 强制把输出 chunk/asset 放到预定义结构,例如所有 chunk 都在 chunks/* 下。这样输出 URL 可以在 transform 钩子里就算出来,不必依赖 renderChunk——HMR patch 文件不会调用 renderChunk,而且 JS 插件的 renderChunk 慢。
  • 插件必须自己 watch 文件并正确注册依赖。非打包模式下刷新总能拿到最新内容;full bundle 模式下内容不会更新,除非 bundle 重新生成或生成 HMR patch 文件。要触发其中之一,插件必须调 this.addWatchFile

CSS HMR 在 8.1.x 下的行为

bundledDev 下 environment.config.isBundledtruevite:css-post 把 CSS 编译成以裸 import.meta.hot.accept() 结尾的 JS 模块,handleHmrOutput 对所有边界硬编码 type: "js-update"。因此 bundled dev 下不会出现 css-update,只出现 js-update

场景unbundledbundled
.css 从 JS importjs-updatejs-update
.css 经 index.html 直接引用css-update(?direct)js-update
.module.css 从 JS importfull-reloadfull-reload
import.meta.hot.accept.jsfull-reloadfull-reload

插件 hotUpdate / handleHotUpdate 的派发是已知缺口,需要 rolldown ≥ 1.2.x,对应 PR #22956。

有一个容易误判的点:有用户最初以为 8.1.5 全是 full-reload,后来发现是测试方法的问题——只用 WebSocket 观察、没有真实浏览器客户端注册模块。实际 8.1.5 中自接受模块有 granular HMR。

后端集成:.vite/manifest.json 没有了

bundledDev 是 pre-compiled 模式和常规 dev server 的混合体。full bundle 模式下,不再有 dev server 渲染的 .vite/manifest.json。Vite 自己在 bundledDev 下用中间件决定 index.html 注入什么,但 vite_rails 绕过了它。

以 vite_ruby 为例(issue:),需要三处改造:

  • dev 期 manifest 生成。bundledDev 下 Vite 把 bundle 输出放在 MemoryFileswatch: { skipWrite: true },插件要在内存里生成 manifest 并用中间件提供。
  • Ruby 侧 manifest reader 的 dev 短路。
  • 代理路由。

Laravel 这类集成也在等 Vite 官方支持。

谁该开,谁别开

值得开分支实测的:

  • 大应用、上千模块的 monorepo
  • dev 启动已经到两位数秒
  • 代理之后刷新明显慢

中小项目在这个模式下拿不到什么收益,不用动实验路径。

项目信息

  • Vite 8.1 公告:
  • Bundled dev mode 设计文档与路线图:
  • Phase 1 反馈:
  • Rolldown:
  • vite_ruby issue #605:
  • Vite 8 发布公告:

推荐文章

程序员茄子在线接单