
Vitest watchTriggerPatterns 实战指南让 watch 模式追踪非 import 的模板、JSON 与生成物【免费下载链接】vitestNext generation testing framework powered by Vite.项目地址: https://gitcode.com/GitHub_Trending/vi/vitestVitest 的 watch 模式基于模块依赖图判断哪些测试需要重跑但对fs.readFile加载的邮件模板、运行时解析的 JSON 配置、构建步骤产出的 HTML/CSS 等“非 import 文件”无能为力。本文围绕 Vitest v3.2.0 引入的watchTriggerPatterns配置说明如何用“正则 回调”显式声明这类隐式依赖并结合源码剖析触发回调的执行链路以及它与forceRerunTriggers的差异与选型依据。问题背景watch 模式依赖 import 图隐式文件依赖会被遗漏在 watch 模式下Vitest 追踪 import 图当某个文件发生变化时所有 import 链能到达该文件的测试都会被重跑。从源码结构看这条逻辑集中在 VitestWatcher 的handleFileChanged方法中——它遍历各 project 的 VitemoduleGraph通过getModulesByFile找到该文件对应的模块再沿mod.importers递归向上回溯把需要重跑的测试文件收集进changedTests集合watcher.ts。这套机制覆盖了大多数场景但存在盲区如果测试依赖的文件从未被import例如用fs.readFile读取的邮件/邮件模板运行时才解析的 JSON fixture由构建步骤拉取的 HTML 或 CSS测试直接断言的生成产物。修改这些文件时import 图里查不到任何 importerwatch 循环无从得知哪些测试已过时相关测试结果会悄悄失效。核心配置用 watchTriggerPatterns 声明“改哪个文件就重跑哪些测试”watchTriggerPatternsv3.2.0 起可用让你显式声明这些依赖提供一个对文件路径求值的正则和一个返回“匹配文件变化时该重跑哪些测试”的回调。最小可用示例vitest.config.tsimport { defineConfig } from vitest/config export default defineConfig({ test: { watchTriggerPatterns: [ { pattern: /src\/templates\/(.*)\.(ts|html|txt)$/, testsToRun: (file, match) { // 编辑 src/templates/welcome.html ⇒ 重跑 api/tests/mailers/welcome.test.ts return api/tests/mailers/${match[1]}.test.ts }, }, ], }, })各要素的语义与约束要素说明pattern对变更文件路径执行的RegExp命中才会调用testsToRuntestsToRun回调参数为(file, match)match是RegExp.exec的结果返回一个或多个待重跑的测试文件路径字符串或字符串数组返回undefined/null/void表示无需重跑路径解析返回的路径相对 workspace root 解析源码中用resolve(config.root, file)拼接且不会被当作 glob 解释必须是具体文件路径配置位置这是全局选项不能写在 project 配置里见 docs/config/watchtriggerpatterns.md 的警告返回的文件应为绝对路径或相对 root 的路径类型定义印证了回调的返回签名见 WatcherTriggerPattern 接口export interface WatcherTriggerPattern { pattern: RegExp testsToRun: ( file: string, match: RegExpMatchArray, ) string[] | string | null | undefined | void }该选项在配置类型中的声明见 InlineConfig.watchTriggerPatterns注释说明其用途是“仅重跑受特定文件变更影响的测试”。多变体写法目录推导与共享 fixture 的一对多映射多个 pattern 可以共存于同一个数组下面两个示例分别演示“由变更文件所在目录推导测试路径”和“单个共享 fixture 映射到固定测试清单”import { defineConfig } from vitest/config export default defineConfig({ test: { watchTriggerPatterns: [ { // 每个模块目录下的 schema.json 变化只重跑该模块的测试 pattern: /src\/(.*)\/schema\.json$/, testsToRun: (_file, match) src/${match[1]}/__tests__/index.test.ts, }, { // 共享 fixture 被多组集成测试使用变化时全部重跑 pattern: /test\/shared-fixture\.json$/, testsToRun: () [ test/integration/users.test.ts, test/integration/billing.test.ts, ], }, ], }, })源码剖析触发回调在 watch 事件流中的位置理解了事件流才能预判 pattern 的副作用边界。VitestWatcher 在registerWatcher中订阅 Vite watcher 的三类事件watcher.tschange→onFileChangeadd→onFileCreateunlink→onFileDelete核心方法getTestFilesFromWatcherTriggerwatcher.ts逐条遍历watchTriggerPatterns对变更路径执行definition.pattern.exec(id)命中后调用definition.testsToRun(id, exec)将返回的字符串或数组逐项resolve(this.vitest.config.root, file)后加入changedTests并返回true表示已触发。值得注意的三个执行细节pattern 命中会短路 import 图回溯。onFileChange中先调用getTestFilesFromWatcherTrigger一旦返回true就直接scheduleRerun(id)不会再进入基于moduleGraph的handleFileChanged分支watcher.ts。这意味着对命中 pattern 的文件Vitest 只按你映射的测试重跑不会顺带重跑 import 图上的其他测试。如果你的模板文件同时被某些测试import了需要自行在testsToRun中补全映射。add事件同样优先走 pattern。新建文件时同样先执行 pattern 匹配watcher.ts——这让你可以为“生成产物首次落盘”这一场景触发重跑而不只是内容修改。回调返回空值则回退到默认逻辑。若testsToRun返回undefined/null/voidtriggered保持false事件流会继续走 import 图判断相当于对该文件保持默认行为。官方 E2E 验证一个最小可复现的完整流程仓库内置了端到端测试验证该能力可作为自查清单。fixture 配置 vitest.config.tsimport { defineConfig } from vitest/config; export default defineConfig({ test: { watchTriggerPatterns: [ { pattern: /folder\/(\w)\/.*\.txt$/, testsToRun: (id, match) { return ./folder/${match[1]}/basic.test.ts; }, } ] } })被测测试 basic.test.ts 用readFileSync读取同目录的text.txt断言其内容为hello world\n——典型的“非 import 文件依赖”。E2E 用例 watchTriggerPattern.test.ts 的验证步骤以watch: true在 fixture 根目录启动 Vitest等待出现Waiting for file changes通过editFile将folder/fs/text.txt中的world替换为vitest等待标准错误输出中出现basic.test.ts即确认该测试被触发重跑断言输出包含expected hello vitest\n to be hello world\n——测试确因文件内容变化而失败证明回调映射的测试确实被执行了。这一用例同时说明了模式匹配的直观效果只改了.txt文件watch 循环就能精确重跑并展示对应测试的新结果。与 forceRerunTriggers 的取舍forceRerunTriggers覆盖的是同一类“隐式依赖”缺口但行为更粗放它是一个 glob 数组类型定义见 config.ts默认值为**/package.json/**和**/{vitest,vite}.config.*命中任一 glob 时handleFileChanged会把state.getFilepaths()的全部测试文件加入changedTestswatcher.ts。而watchTriggerPatterns只重跑你为具体 pattern 映射的测试能保持 watch 循环的响应速度。选型建议配置文件类变更package.json、vitest.config.*→ 用默认的forceRerunTriggers全部重跑是合理代价模板、fixture、生成物等高频编辑文件 → 用watchTriggerPatterns精确映射避免每次改一个模板都触发全量重跑。小结watchTriggerPatterns是 Vitest v3.2.0 引入的全局配置用pattern对文件路径求值的RegExp加testsToRun回调返回相对 root 的具体测试文件路径非 glob显式声明非 import 的文件依赖命中 pattern 的 change/add 事件会短路 import 图回溯只重跑映射的测试回调返回空值则回退到默认行为多 pattern 可共存支持“按目录推导”与“一对多固定清单”两类映射需要全量重跑的粗粒度场景交给forceRerunTriggers精确重跑交给watchTriggerPatterns相关文档watchTriggerPatterns、forceRerunTriggers官方发布说明见 docs/blog/vitest-3-2.md。【免费下载链接】vitestNext generation testing framework powered by Vite.项目地址: https://gitcode.com/GitHub_Trending/vi/vitest创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考