2.4 开发循环

生成模型:Claude Opus 4.6 (anthropic/claude-opus-4-6) Token 消耗:输入 ~140,000 tokens,输出 ~10,000 tokens(本章合计)


高效的开发循环是贡献开源项目的基础。OpenClaw 提供了多种工具来加速"修改 → 验证"的反馈循环。

2.4.1 pnpm gateway:watch — 文件监听与热重载

对于 Gateway 开发,最常用的命令是:

pnpm gateway:watch

这个命令的实现在 scripts/watch-node.mjs 中,它做了两件事:

// scripts/watch-node.mjs(简化)

// 1. 先执行一次完整构建
const initialBuild = spawnSync("pnpm", ["exec", "tsdown"], { stdio: "inherit" });

// 2. 同时启动两个进程:
// (a) tsdown --watch:监听 TypeScript 源码变更,增量重新编译
const compilerProcess = spawn("pnpm", ["exec", "tsdown", "--watch"], { stdio: "inherit" });

// (b) node --watch:监听 dist/ 中的 JS 变更,自动重启 Gateway
const nodeProcess = spawn(
  process.execPath,
  ["--watch", "openclaw.mjs", ...args],
  { stdio: "inherit" }
);

工作流程如下:

注意 --watch 是 Node.js 22 内置的文件监听重启功能,不需要额外的 nodemon 等工具。

还有一个跳过通道连接的开发模式,适合只开发 Gateway 核心逻辑时使用:

这两个命令设置了环境变量 OPENCLAW_SKIP_CHANNELS=1,让 Gateway 启动时不连接任何通道(WhatsApp、Telegram 等),大幅缩短启动时间。

智能增量构建

scripts/run-node.mjs 实现了一个智能增量构建机制:

它通过比较 .buildstamp 文件与 src/ 目录下最新文件的修改时间来判断是否需要重新构建。这样在运行 pnpm openclaw gateway 时,如果你没有修改任何源文件,就会跳过构建直接启动——节省了几秒钟的启动时间。

2.4.2 测试体系

OpenClaw 拥有一套完善的分层测试体系:

单元测试

单元测试使用 vitest,配置在 vitest.config.ts 中。测试文件与源码放在同一目录下,以 .test.ts 后缀命名:

vitest 的关键配置:

  • 进程隔离pool: "forks"):每个测试文件在独立进程中运行。这对于 OpenClaw 很重要,因为 Gateway 测试可能涉及全局状态(端口绑定、文件锁等)。

  • 排除 live 和 e2e 测试:这些需要真实 API Key 或完整环境,单独运行。

端到端测试(E2E)

E2E 测试(*.e2e.test.ts)验证完整的用户流程——启动 Gateway、发送消息、验证回复。它们使用 vitest.e2e.config.ts 配置。

Live 测试

Live 测试(*.live.test.ts)需要真实的 API Key(如 Anthropic API Key、OpenAI API Key),测试与真实模型的交互。通过环境变量 OPENCLAW_LIVE_TEST=1 启用。

Docker 测试

Docker 测试在容器中运行,验证打包、安装、网络等场景:

测试
说明

test:docker:live-models

容器中测试模型调用

test:docker:live-gateway

容器中测试 Gateway

test:docker:onboard

容器中测试引导向导

test:docker:gateway-network

容器网络测试

test:docker:qr

QR 码导入测试

test:docker:doctor-switch

doctor 命令测试

test:docker:plugins

插件测试

并行测试运行器

OpenClaw 有一个自定义的并行测试运行器 scripts/test-parallel.mjs,被 pnpm test 调用。它将测试文件分成多个批次并行运行,充分利用多核 CPU。

UI 测试

Web UI 有自己的测试配置(ui/vitest.config.ts),使用 @vitest/browser-playwright 在真实浏览器中运行。

2.4.3 代码质量:oxlint 类型感知 Lint + oxfmt 格式化

Lint 检查

OpenClaw 使用 oxlint(Rust 编写的 Linter)而非 ESLint。oxlint 的优势在于速度——对于 OpenClaw 数十万行的代码库,oxlint 的 lint 时间只有 ESLint 的几十分之一。

--type-aware 标志启用类型感知规则,这意味着 oxlint 会读取 TypeScript 的类型信息来进行更精确的检查(例如检测未使用的类型导入、类型不安全的比较等)。

格式化

oxfmt 处理代码格式化。配置在 .oxfmtrc.jsonc 中。

Swift 代码质量

原生应用的 Swift 代码有独立的 Lint 和格式化工具:

配置文件 .swiftlint.yml.swiftformat 分别定义了规则。

文档质量

check:loc 通过 scripts/check-ts-max-loc.ts 确保没有单个 TypeScript 文件超过 500 行——这是一个代码组织的硬性约束。如果一个文件增长到接近 500 行,就应该考虑拆分。

一键质量检查

Git Hooks

OpenClaw 通过 git-hooks/ 目录配置了 Git 钩子,在 prepare 脚本中设置:

这确保了每次 commit 之前自动运行 lint 和格式化检查。


总结一下 OpenClaw 的开发工作流:

到这里,你已经具备了参与 OpenClaw 开发所需的全部环境知识。从下一章开始,我们将深入 Gateway 控制平面的源码实现。

Last updated