ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

airi 仓库实战:tsdown 监听模式(Watch Mode)配置完全指南

airi 仓库实战:tsdown 监听模式(Watch Mode)配置完全指南
  • 人工智能
  • AI Agent
  • MCP 服务
  • 工具调用
  • GUI 自动化
  • 语音
  • 数字人
  • 交互助手

【免费下载链接】airi

💖🧸 自托管、归你拥有的 Grok 风格 AI 伴侣与 waifu / 赛博生命灵魂容器,目标是接近 Neuro-sama 的高度;支持实时语音聊天、Minecraft 和 Factorio 游玩,支持 Web / macOS / Windows。

项目地址:https://gitcode.com/moeru-ai/airi
点击查看免费下载

tsdown 是 airi 仓库中用于打包 TypeScript/JavaScript 库的核心构建工具,其监听模式(Watch Mode)能够在源码变更时自动重建产物,显著缩短库开发的迭代反馈回路。本文以 tsdown 的 Watch Mode 官方参考文档为主体,结合 airi 仓库中真实存在的tsdown.config.ts配置文件(如 packages/core-agent/tsdown.config.ts、packages/i18n/tsdown.config.ts),系统讲解监听模式的 CLI 用法、配置项、高级模式与故障排查,读完即可在自己的库开发流程中落地一套高效、可复制的热重建工作流。

一、Watch Mode 是什么

Watch Mode 会持续监控你的源文件,并在文件发生变化时自动触发重新构建,从而把"改代码 → 手动跑构建 → 查看产物"的多步流程压缩为"改代码 → 自动出产物"一步。它面向的是开发阶段,而非生产发布:

  • 监听期间每次构建都是增量式的,只重编发生变化的模块链,比全量构建更快;
  • 你可以把测试、启动 dev server 等后续动作挂在构建成功之后(onSuccess),让产物一变,测试或本地服务立刻跟上;
  • 它不要求你手动反复执行tsdown,是 tsup 用户迁移到 tsdown 后首选的开发替代方案。

tsdown 基于 Rolldown 与 Oxc 构建,运行时要求 Node.js 22.18.0 或更高(仅构建期);但产物可以通过target选项降级到更低的 Node.js 版本,不影响库的运行时兼容性。相关基础说明可参考 tsdown SKILL 文档 与 Getting Started 指南。

二、基础用法:CLI 与配置文件

2.1 CLI 启动

# 监听所有项目文件 tsdown --watch # 或使用短标志 tsdown -w # 监听指定目录 tsdown --watch ./src # 监听指定文件 tsdown --watch ./src/index.ts

--watch与-w完全等价;--watch后面还可以跟一个可选的路径参数,用于把监听范围收敛到某个目录或单个入口文件(参见 CLI Reference 中--watch, -w [path]一节)。

2.2 配置文件启用

export default defineConfig({ entry: ['src/index.ts'], watch: true, })

设置watch: true后,只要以tsdown启动(无需额外加--watch),便会进入监听模式。CLI 标志与配置文件的关系遵循"CLI 覆盖配置文件"的优先级规则:--no-watch可以临时关闭配置文件中的监听开关。

三、Watch 选项详解

3.1 忽略路径(Ignore Paths)

某些文件(如测试、fixtures、临时文件)的变动不应触发重建,可通过--ignore-watch排除:

tsdown --watch --ignore-watch test --ignore-watch '**/*.test.ts'

配置文件中的等价写法使用watch.exclude:

export default defineConfig({ entry: ['src/index.ts'], watch: { exclude: ['test/**', '**/*.test.ts'], }, })

3.2 构建成功后执行命令(On Success Command)

监听模式下最常见的需求是"构建完立刻做点什么"——跑测试、启动服务、发通知:

# 构建成功后打印提示 tsdown --watch --on-success "echo Build complete!" # 构建成功后直接运行产物 tsdown --watch --on-success "node dist/index.mjs"
export default defineConfig({ entry: ['src/index.ts'], watch: true, onSuccess: 'node dist/index.mjs', })

onSuccess接收的是 shell 命令字符串,仅在构建成功时执行;构建失败时不会触发,方便你在出错时直接查看终端中的报错而非被后续命令掩盖。更多用法见 On Success。

四、Watch 行为机制

4.1 默认监听目标

默认情况下 tsdown 监听三类内容:

  • 所有入口文件(entry中声明的文件);
  • 所有被入口导入的文件(import 链上的模块);
  • 配置文件本身(如tsdown.config.ts,变更时触发重启)。

这意味着监听范围是跟随模块依赖图动态变化的:新增一个被入口导入的文件,它会自动进入监听范围;反之,从依赖图中移除的文件也会自动退出监听,无需手动维护路径列表。

4.2 文件变更处理策略

不同文件的变更触发不同级别的处理:

变更对象处理方式
源文件增量重建(incremental rebuild)
配置文件完全重启,并清空缓存(full restart with cache clear)
依赖(dependencies)若被入口导入则重建对应模块

配置文件的变更之所以要"完全重启",是因为解析配置后缓存了入口、格式、插件等关键决策,热替换容易引入不一致状态;直接重启反而最可靠。

4.3 键盘快捷键

监听进程存活期间可直接用键盘控制:

  • r—— 手动触发一次重建(手动重建);
  • q—— 退出监听模式。

这两个快捷键让"手动控制构建节奏"无需另开终端,配合onSuccess使用尤其顺手。

五、常见模式:把 Watch 用出生产力

5.1 开发模式一键切换

利用defineConfig支持函数参数的特性,可以基于options.watch一键在"开发"与"生产"两套配置间切换:

export default defineConfig((options) => ({ entry: ['src/index.ts'], format: ['esm'], watch: options.watch, sourcemap: options.watch, // 开发时生成 source map 便于调试 minify: !options.watch, // 生产时才压缩 }))

关于sourcemap的三种形态(外置 / inline / hidden)及与watch的搭配,见 Sourcemap 文档。

5.2 构建后自动跑测试

把测试作为onSuccess,实现"保存即测":

export default defineConfig({ entry: ['src/index.ts'], watch: true, onSuccess: 'npm run test', })

5.3 多入口监听

对象形式的entry同样受支持,多个入口各自产出独立 bundle:

export default defineConfig({ entry: { main: 'src/index.ts', cli: 'src/cli.ts', }, watch: true, clean: false, // 每次重建不清空输出目录 })

clean: false在监听模式下的意义在于:反复重建时避免反复清空/重写整个输出目录,加快增量构建。完整的行为权衡见 Cleaning 文档。

5.4 与测试运行器 / dev server 集成

# 变更后自动跑 vitest tsdown --watch --on-success "vitest run" # 变更后自动重启本地服务 tsdown --watch --on-success "node dist/server.mjs"

airi 仓库中大量包都同时配备了 tsdown 与 vitest(如 packages/core-agent、packages/provider-inference),这一组合正是上述模式的典型应用场景。

5.5 Monorepo 包监听

结合workspace支持,一份配置即可监听多个子包:

export default defineConfig({ workspace: 'packages/*', entry: ['src/index.ts'], watch: { exclude: ['**/test/**', '**/*.spec.ts'], }, })

原文档此处同时声明了顶层watch: true与watch: { exclude }两个同名键,二者语义等价于"开启监听并排除测试路径"。在真实的 TypeScript 配置中,请像上面这样把exclude收敛进watch对象里,避免同名键覆盖。

airi 仓库即采用 pnpm workspace + tsdown 的 monorepo 布局(见根目录 package.json 与 pnpm-workspace.yaml),仓库内共有 35 个tsdown.config.ts,例如:

  • packages/plugin-sdk/tsdown.config.ts:多入口 +dts: true+format: 'esm';
  • services/computer-use-mcp/tsdown.config.ts:多入口 +target: 'node18'+clean: true+dts: true;
  • packages/audio/tsdown.config.ts:对象入口 +unbundle: true+external;
  • packages/i18n/tsdown.config.ts:对象入口 +copy+unbundle: true+ unplugin 插件。

给这些包的开发流程加上--watch,即可在改动任一子包源码后即时获得增量产物。

六、高级配置

6.1 自定义 Watch 选项

watch除了true/false,还支持对象形式以精细化控制:

export default defineConfig({ entry: ['src/index.ts'], watch: { include: ['src/**'], // 额外纳入监听的路径 exclude: ['**/*.test.ts', '**/fixtures/**'], // 忽略的 glob 路径 skipWrite: false, // 是否跳过写入产物 }, })
  • include:在默认监听目标(入口 + 导入链 + 配置文件)之上,追加需要关注的目录;
  • exclude:从监听范围中剔除的 glob 模式,防止测试、fixtures 等无关变更触发重建;
  • skipWrite:控制重建后是否实际写出产物文件,对"只想验证构建不落盘"的场景有用。

6.2 条件式 Watch(Conditional Watch)

在函数式配置中按 watch 状态裁剪能力,让同一份配置同时服务开发与发布:

export default defineConfig((options) => { const isDev = options.watch return { entry: ['src/index.ts'], format: ['esm'], dts: !isDev, // 监听模式下跳过 DTS 生成,加快重建 sourcemap: isDev, clean: !isDev, } })

这里的关键取舍:dts(类型声明生成)与minify(压缩)都是重建耗时大户,开发期关闭、发布期开启,是让 watch 保持"秒级反馈"的核心技巧。DTS 相关的isolatedDeclarations加速手段见 DTS 文档。

七、CLI 速查表

# 基础监听 tsdown -w # 监听 + source map tsdown -w --sourcemap # 监听但不清理输出目录 tsdown -w --no-clean # 监听 + 构建成功后执行命令 tsdown -w --on-success "npm test" # 只监听指定格式 tsdown -w --format esm # 监听 + 压缩 tsdown -w --minify # 监听 + 忽略测试文件 tsdown -w --ignore-watch '**/*.test.ts'

八、使用建议

  1. 活跃开发时始终开启 watch mode,让产物时刻保持与源码同步;
  2. 监听模式下跳过 DTS 生成(dts: !options.watch),重建速度显著提升;
  3. 关闭clean,避免每次重建做多余的文件系统操作;
  4. 善用onSuccess挂载测试、lint、重启 dev server 等后置任务;
  5. 忽略测试文件(exclude: ['**/*.test.ts']),防止无关变更触发无效重建;
  6. 记住r/q快捷键,需要时手动重建或随时退出监听。

九、故障排查

9.1 变更未被监听

依次检查:

  • 文件是否位于entry或入口的 import 依赖链上(默认只监听这两类 + 配置文件);
  • 路径是否命中了exclude或--ignore-watch的忽略模式;
  • 文件系统是否支持监听(网络盘、部分容器/挂载卷可能不触发事件)。

9.2 重建过于频繁

把明显无关的路径全部排除掉:

export default defineConfig({ watch: { exclude: [ '**/node_modules/**', '**/.git/**', '**/dist/**', '**/*.test.ts', ], }, })

9.3 重建速度慢

  • 监听模式下跳过 DTS:dts: !options.watch;
  • 关闭压缩:minify: false;
  • 开发期间收窄入口集合,减少每次全量处理的模块数。

9.4 配置变更未生效

配置文件一旦变更,tsdown 会自动触发完全重启并清空缓存,因此不需要手动干预。若感觉改动没生效,请确认改动的是被自动发现的配置文件本身(配置文件查找规则),而不是某个未被监听的引用文件。

9.5 为什么不用 Stub Mode?

tsdown不支持 stub mode。对于快速开发,官方推荐以 watch mode 作为替代方案——它在没有 stub mode 诸多弊端(如类型解析不一致、产物与源码脱节)的前提下,提供即时重建的体验。

十、相关选项

  • On Success —— 构建成功后执行命令;
  • Sourcemap —— 调试信息生成;
  • Clean —— 输出目录清理策略。

完整 CLI 参考见 reference-cli.md,技能总览见 tsdown SKILL.md。结合 airi 仓库中 35 个真实存在的tsdown.config.ts(如 packages/plugin-sdk/tsdown.config.ts、services/computer-use-mcp/tsdown.config.ts),你可以直接把本文的 watch 模式配置接入任意一个子包的开发脚本,享受"保存即重建、重建即验证"的开发体验。

  • 人工智能
  • AI Agent
  • MCP 服务
  • 工具调用
  • GUI 自动化
  • 语音
  • 数字人
  • 交互助手

【免费下载链接】airi

💖🧸 自托管、归你拥有的 Grok 风格 AI 伴侣与 waifu / 赛博生命灵魂容器,目标是接近 Neuro-sama 的高度;支持实时语音聊天、Minecraft 和 Factorio 游玩,支持 Web / macOS / Windows。

项目地址:https://gitcode.com/moeru-ai/airi
点击查看免费下载

相关推荐

上一篇:aliyunpan 排障速查指南:登录失败、下载上传与同步备份问题定位
下一篇:node-postgres增删改查完全手册:参数化查询与结果集处理,彻底告别SQL注入

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进