看看vitest5有啥更新
Vitest 5.0 在 2026-09-03 正式发布了,官方博客和 GitHub release notes 我都看了,这版主打性能,顺带塞了一批新 API。 先说最硬的:性能提升 官方这次专门搭了 vitest-dev/benchmarks,用真实项目测(从 5 个文件的工具库到 1280 模块的企业级 monolith),而不是跑微基准。几个代表性数字(4.1.10 → 5.0,Apple M4 / Node 24): - deps-heavy + vmThreads:1.59s → 0.74s,快 53% - long-haul 80 个 jsdom 文件 + vmForks:5.43s → 4.06s,快 25% - enterprise-monolith(1280 模块,forks + isolate):7.24s → 5.83s,快 19% - barrel-hell(817 模块):1.33s → 1.08s,快 18% - react-spa Browser Mode:2.40s → 2.01s,快 16% - node-library(forks 隔离):0.86s → 0.75s,快 13% - 已经瓶颈在环境初始化的场景(forks + jsdom + isolate)基本在 ±3% 内,没变差 背后的机制:inline projects 共享 Vite server(test.projects 里没改 Vite 配置的项目直接复用父级 server,共享文件只 transform 一次);fsModuleCache 从 experimental.fsModuleCache 转正成顶层选项,把 transform 结果落盘,跨 rerun 和跨进程复用,插件还能用 defineCacheKeyGenerator 参与缓存 key;vm 池复用编译产物、预热模块图,并且支持 require(esm);Browser Mode 预打包运行时、浏览器在 Vite server 启动时就预热、按需开 session 而不是一上来开 maxWorkers 个;Vitest 现在自带依赖打包,node_modules 里的包数量少了。 另外 reporter 输出的耗时拆解现在带百分比,比如 Duration 3.76s (environment 79% import 13% transform 6% tests 1% setup 1%),一眼看出时间花哪了。还会默认打印性能提示,另外新增 vitest doctor 命令,用不同配置跑一遍你的测试,告诉你哪些选项能让它更快。 新功能里最值得看的几个 1)Trace View(Browser Mode 内建) 开 browser.traceView 之后,Vitest 把每次交互、断言、page.mark 都录成 DOM 快照,浏览器已经走过去了你还能一步步回放。浏览器 UI、Vitest UI、HTML reporter 里都能看,本地调试和 CI 失败都能用。选某一步能看到当时的页面重建状态,交互元素高亮,失败的动作和断言标红,还支持键盘导航和 watch 模式实时更新。官方特意强调:不依赖 provider,也不需要单独的 viewer(这点和 Playwright Trace 不同)。 2)嵌套 projects 和配置继承 inline project 现在默认继承根配置,包括 plugins、resolve.alias 这些 Vite 选项——Vitest 4 里得每个 project 手写 extends: true。test.projects 里引用的配置文件自己也能声明 projects,当作容器用,生成 app (unit)、app (e2e) 这种嵌套名字,这样可以直接引用一个已经定义了自己 projects 的 package,不用在根上重复写。--project 过滤能感知层级,还加了 -p 简写,比如 vitest -p app。 3)vi.when:按参数定义 mock 行为 以前要给不同参数返回不同值,得自己写 mockImplementation 里判断参数。现在: vi.when(findById).calledWith(1).thenResolve({...}).calledWith(2).thenResolve({...}).calledWith(expect.any(Number)).thenReject(new Error('not found')) 参数用深比较匹配,支持 expect.any 这类非对称匹配器。可以用 thenReturnOnce 或 times 限制次数,新增 toHaveBeenExhausted 断言检查每个注册行为都被消费过。 4)Benchmark API 重写 bench 不再是顶层导入,变成 test 里的 fixture,所以基准测试能用上 test runner 的一切:fixtures、生命周期钩子、retry、过滤、断言。写法变成 test('compare parsers' async ({ bench }) => { const result = await bench.compare(bench('JSON.parse',...) bench('custom parser',...)); expect(result.get('JSON.parse')).toBeFasterThan(result.get('custom parser')) })。结果可以用 writeResult 存、bench.from 回放对比 baseline,内置 Tinybench provider 也能换成自定义 provider,基准输出进了 default 和 json reporter。 5)locator 报错会打 ARIA 树 Browser Mode 里 locator 找不到元素时,除了 HTML 还会打被搜索子树的 ARIA snapshot——无障碍树通常比原始 HTML 短得多,而且正好是 getByRole / getByLabelText 匹配的 role 和 name。用 browser.locators.errorFormat 控制,可选 html / aria / all。locator 也默认严格了,locators.exact 打开,getByText('Item') 不会再误匹配 Item 1。 6)Mock Temporal fake timers 现在连带把 Temporal API 也 mock 了(靠 @sinonjs/fake-timers v15.4),vi.useFakeTimers 和不用 fake timers 的 vi.setSystemTime 都生效。Temporal 进了默认 fake 集合,不想 fake 就加到 toNotFake 里。 7)断言更严格 resolves、rejects、toMatchFileSnapshot 这类异步断言没 await 现在直接让测试失败(以前是测试结束时代劳 await,只打个警告,结果断言实际没跑到,测试还过了)。expect.poll 超时没 settle 就 reject,并且回调能收到 AbortSignal,方便取消进行中的请求。 断言类型也改了:Matchers 接口第一个参数变成返回类型,能同时表达返回类型和接收类型,自定义 matcher 还能拿到底层 Chai 的 assertion 对象。 8)clearMocks 默认开启 默认 true,每个测试前调 vi.clearAllMocks,mock 不再把调用历史带到下一个测试,但实现保持不变。这直接干掉了一大类顺序依赖的 flaky 测试。想保留旧行为就 clearMocks: false。 9)Reporter 统一输出目录 html、json、junit reporter、attachmentsDir、失败截图、新的 trace 全都默认写进项目根目录的.vitest,.gitignore 从一堆条目变一条。第三方 reporter 可以用新的 vitest.createReport(scope) 走同样约定。HTML reporter 还能出单文件报告,singleFile: true 把 UI 资源、元数据、附件全内联进一个 index.html,传 CI artifact 很方便。 其他零碎的 --repeats 不管结果重复跑每个测试指定次数,专门抓 flaky;injectCjsGlobals 可以关掉往 ESM 里注入 module/exports/require/__filename/__dirname;coverage.autoAttachSubprocess 用 v8 provider 追踪测试期间起的 node:child_process 和 node:worker_threads 覆盖率;coverage.thresholds.perFile 现在接受对象,thresholds.autoUpdate 能收到上一次阈值;junit reporter 支持 jest-junit 兼容命名选项;TestCase.logs 把测试期间的 console 输出暴露给 reporter 和高级 API;测试标题和 inspect 值改用 pretty-format,test.for/each 的标题占位符支持非 ASCII 字符;vitest --merge-reports 支持跨多环境的非分片运行;istanbul 换到维护中的 @vitest/istanbuljs 包。 破坏性变更,升级前注意 - 环境要求:Node.js >= 22.12.0,Vite >= 6.4.0 - clearMocks 默认变 true - 异步断言不 await 直接失败 - bench 不再是顶层导出,公共 API 重写 - sequential 测试/套件选项移除,统一用 concurrent - locator 从字符串变成对象;locators.exact 默认开;toHaveTextContent 变严格,宽匹配用新的 toMatchTextContent - Matchers 接口签名变了(第一个参数是返回类型) - 不再从祖先目录查找配置文件 - attachmentsDir 默认从.vitest-attachements/ 改成.vitest/attachments/;json/junit 输出默认进.vitest;blob reporter 和 --merge-reports 默认.vitest/blob/ - loupe.inspect 换成 pretty-format;expect 包、@vitest/runner 包被 inline 不再单独发布;删了一批废弃入口 - webdriverio 包移除 - hoistable 方法放在顶层作用域之外会直接报错 - vi.mock 的 hoist 行为、mock 在 doMock 队列顺序、spy 对 class 原型方法的处理等也都有调整 完整变更清单在 GitHub 的 v5.0.0 release notes,详细迁移步骤在 vitest.dev/guide/migration。如果你是要把哪个项目升上去,告诉我用的 Node/Vite 版本和有没有用 browser mode、workspace,我帮你对一下哪几条会踩到。