Langfuse Monorepo 中的 Turbo watch:依赖感知的任务自动重跑与持久化任务模式
Langfuse Monorepo 中的 Turbo watch依赖感知的任务自动重跑与持久化任务模式【免费下载链接】langfuse Open source AI engineering platform: LLM evals, observability, metrics, prompt management, playground, datasets. Integrates with OpenTelemetry, LangChain, OpenAI SDK, LiteLLM, and more. YC W23项目地址: https://gitcode.com/GitHub_Trending/la/langfuse本文以 Langfuse 仓库内置的 Turborepo 技能文档 watch/RULE.md 为主体完整讲解turbo watch命令的用法、持久化persistent任务的两种模式、watch 模式的已知限制以及它与turbo run的差异。同时结合 Langfuse 根目录的 turbo.json、package.json 等真实配置说明该命令在这类 pnpm Turborepo 单体仓库monorepo中的落地方式。读完本篇你可以掌握开发期任务自动重跑的完整工作流并能在自己的 Turborepo 项目中正确配置 persistent / interruptible 任务。turbo watch 是什么一句话定位与适用场景turbo watch的定位非常明确在代码变更时自动重跑任务且具备依赖感知dependency-aware能力。turbo watch [tasks]官方完整文档见 Turborepo 站点的 watch 参考页此处按仓库内技能文档转述不输出外部链接。它和turbo run的核心差异在技能文档中给出一张对比表这里完整继承Featureturbo runturbo watchRuns onceYesNoRe-runs on changeNoYesCachingFullExperimentalUse caseCI, one-offDevelopment从这张表可以得出选型原则CI 流水线和一次性执行用turbo run本地开发期需要改代码即重跑的场景用turbo watch。在 Langfuse 仓库中根 package.json 的 scripts 几乎全部通过turbo run委托如build: turbo run build、dev: turbo run dev、typecheck: turbo run typecheck而根目录的 turbo.json 则定义了这些任务在依赖图中的执行顺序——这正是不论run还是watch都由turbo.json说了算的直接体现。基本用法单任务与多任务监听文档给出的基本用法示例如下# Watch and re-run build task when code changes turbo watch build # Watch multiple tasks turbo watch build test lint行为要点是当源文件发生变化时任务会按照在turbo.json中配置的顺序重跑。这一点在 Langfuse 的 turbo.json 中可以找到真实对应。例如build任务声明了build: { dependsOn: [db:generate, ^build], env: [NEXT_IGNORE_BUILD_ERRORS], outputs: [dist/**, .next/**, !.next/cache/**], cache: true, outputLogs: errors-only }其中dependsOn: [db:generate, ^build]意味着 build 重跑前会先确保 Prisma 客户端生成db:generate以及所有上游包的build^build表示依赖包的同名任务完成。若用turbo watch build监听任何一次源文件变更触发的重跑都会遵循这条依赖链而不是简单地重新执行next build或tsc。仓库在 turbo.json 中甚至用注释解释了缓存与类型检查的关系NEXT_IGNORE_BUILD_ERRORS会切换 Next.js 的类型检查因此检查过与未检查的构建不能共享同一条缓存记录——这正是 watch 场景下缓存正确性需要考虑的细节。持久化任务persistent 与 interruptible 的两种模式这是 watch 文档中最关键的进阶内容。持久化任务persistent: true如 dev server不会退出因此不能被其他任务依赖这一点在turbo watch中与turbo run的行为完全一致。文档进一步区分了两类持久化任务模式一自带 watcher 的工具Dependency-Aware如果你的工具本身内置了文件监听例如next dev、vite dev直接依赖它自己的 watcher 即可turbo.json中典型配置为{ tasks: { dev: { persistent: true, cache: false } } }Langfuse 正是这种模式。根 turbo.json 中定义了三个开发任务dev: { cache: false, persistent: true, dependsOn: [db:generate] }, dev:web: { cache: false, persistent: true, dependsOn: [db:generate] }, worker#dev: { cache: false, persistent: true }对应到各包的实际命令web/package.json 中dev: dotenv -e ../.env -- next dev——next dev自带 HMR 与文件监听worker/package.json 中dev: dotenv -e ../.env -- tsx watch --clear-screenfalse --include ../packages/shared/dist/* src/index.ts——tsx watch是 tsx 自带的文件监听模式并且通过--include参数把共享包langfuse/shared的构建产物目录也纳入监听范围。从这两个实现可以推断 Langfuse 的设计取舍dev server 层已经具备对源码变更的感知能力包括对packages/shared/dist这类跨包产物的监听因此不需要再套一层turbo watch来重跑 dev 任务。根 package.json 也提供了细粒度的过滤入口dev:worker: turbo run dev --filterworker, dev:web: turbo run dev --filterweb, dev:web-webpack: turbo run dev --filterweb -- --webpack模式二不自带 watcher 的工具Non-Dependency-Aware对于无法感知上游依赖变更的工具文档推荐启用interruptible{ tasks: { dev: { persistent: true, interruptible: true, cache: false } } }开启后turbo watch会在依赖上游包产物、输入文件等发生变化时先中断并重启这些 interruptible 任务。这是工具自身 watcher 覆盖不到依赖图变化时的补偿机制——监听工作由 turbo 接管工具只需被干净地杀掉和重启。两个模式的选型逻辑可以归纳为场景配置谁负责检测变更工具自带 watchernext dev、vite、tsx watchpersistent: true工具自身工具不感知依赖变更persistent: trueinterruptible: trueturbo watch重启进程限制一watch 模式下的缓存是实验性的文档明确指出watch 模式下的缓存目前是实验特性需要显式开启写缓存turbo watch your-tasks --experimental-write-cache这与对比表中 Caching: Experimental 对应。对 Langfuse 仓库的启示是开发期如果追求永远执行真实构建直接使用turbo run的--force或依赖任务自身的cache: false声明例如 Langfuse 中所有db:*任务均声明了cache: false见 turbo.json比依赖 watch 的实验缓存更稳妥。另外CONTRIBUTING.md 中还有一条与缓存行为直接相关的实战提示lint和typecheck这类任务是有缓存的一次通过可能是历史缓存的重放replay。文档建议同时阅读 turbo 输出的Cached:行与Tasks:行必要时用--force重跑例如pnpm exec turbo run lint --force。这条经验对 watch 模式同样适用——判断这次重跑到底是真跑还是命中缓存需要看输出细节而不是只看退出码。限制二任务输出被 git 跟踪可能导致无限循环文档给出的警告是如果任务会把文件写回 git 跟踪的目录watch 模式可能无限循环——任务写出文件 → 文件变更触发重跑 → 再写出文件 → 再触发……watch 模式虽然使用文件哈希来规避这一问题但并非万无一失。文档的官方建议只有一句把任务输出从 git 中移除Remove task outputs from git。对照 Langfuse 的 turbo.json各任务的输出声明outputs为build: { outputs: [dist/**, .next/**, !.next/cache/**] }, build:check: { outputs: [.next-check/**, !.next-check/cache/**] }, lint: { outputs: [] }可以看到 Langfuse 严格遵循了这一原则构建产物集中在dist/、.next/且用!.next/cache/**排除缓存目录、.next-check/web/package.json 中build:check通过NEXT_DIST_DIR.next-check把校验构建输出到独立目录可与 dev server 并行这些不受版本控制的目录lint则显式声明outputs: []表示不产生需要缓存的输出。这类产物目录与源码目录隔离的布局正是避免 watch 无限循环的具体工程手段。Langfuse 场景下的常见模式技能文档最后给出两个通用模式下面结合 Langfuse 仓库做等价落地说明。开发工作流dev server build 监听# Run dev servers and watch for build changes turbo watch dev build如前所述Langfuse 的 dev 任务自带 watcher因此仓库实际采用的是pnpm run dev即turbo run dev同时拉起 web 与 worker 的持久化进程。如果你在自己的项目中混用了有 watcher 的 dev与需要重跑的 buildturbo watch dev build就是文档给出的标准组合。开发期持续类型检查# Watch and re-run type checks turbo watch check-typesLangfuse 的等价任务是typecheck根脚本pnpm tc即turbo run typecheck。turbo.json 中其定义为typecheck: { dependsOn: [db:generate, ^build], cache: true, outputLogs: errors-only, outputs: [] }而 web/package.json 的具体实现是typecheck: dotenv -e ../.env -- tsc -p tsconfig.json --noEmit --skipLibCheck --incremental --tsBuildInfoFile .tsbuildinfo注意--incremental --tsBuildInfoFile .tsbuildinfoTypeScript 增量编译把构建信息写入.tsbuildinfo使得每次重跑只做增量检查这大幅降低了watch 模式反复触发 typecheck的开销。把turbo watch typecheck这类用法叠加在增量编译之上是大型 monorepo 中常见的开发期类型检查实践。总结watch 模式的使用决策清单把技能文档的要点与 Langfuse 仓库证据合并可以得到一份可复用的决策清单一次性执行 / CI 用turbo run开发期自动重跑用turbo watch对比表四行差异任务顺序永远由turbo.json的dependsOn决定watch 只是在其之上叠加文件监听参考 turbo.json 中build、typecheck、dev的依赖声明持久化任务不能被依赖next dev、tsx watch这类自带 watcher 的工具只配persistent: truecache: false不自带 watcher 的工具追加interruptible: true由turbo watch负责在依赖变化时重启watch 下缓存是实验特性写缓存需--experimental-write-cache判断真跑还是缓存重放要看Cached:输出行必要时--force见 CONTRIBUTING.md任务产物绝不进 git并像 Langfuse 一样通过outputs明确声明产物边界dist/**、.next/**、!.next/cache/**从源头规避 watch 无限循环风险。适用前提说明上述行为基于仓库根 package.json 声明的环境——Node 24、pnpm 12.3.1、turbo 2.10.5以及 pnpm workspacespnpm-workspace.yaml 纳入了web、worker、packages/**与ee等包。在其他 Turborepo 版本上迁移这些配置时建议以你所用版本turbo.json的 schema 校验结果为准。【免费下载链接】langfuse Open source AI engineering platform: LLM evals, observability, metrics, prompt management, playground, datasets. Integrates with OpenTelemetry, LangChain, OpenAI SDK, LiteLLM, and more. YC W23项目地址: https://gitcode.com/GitHub_Trending/la/langfuse创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考