OpenCode Formatters 完全指南:让 AI 生成代码自动符合团队规范

OpenCode Formatters 完全指南:让 AI 生成代码自动符合团队规范

引言

在使用 AI 编程助手时,一个常见的痛点就是生成的代码格式不统一。每个人的编码风格不同,AI 模型训练数据中的风格更是五花八门。如果你的项目使用 Prettier、ESLint、Ruff 等工具来保证代码风格一致性,那么手动格式化 AI 生成的每一段代码无疑是一件令人崩溃的事。

OpenCode 内置了 Formatters(格式化器)系统,能够在每次写入或编辑文件后自动运行语言特定的格式化工具,确保 AI 生成的代码从第一行起就符合你的项目规范。本文将详细讲解 OpenCode Formatters 的配置与使用。

什么是 OpenCode Formatters?

OpenCode Formatters 是一套在 AI 完成文件写入或编辑后自动触发的格式化机制。它支持大量主流语言的格式化工具,从 JavaScript/TypeScript 的 Prettier、Python 的 Ruff、Go 的 gofmt,到 PHP 的 Pint、Rust 的 rustfmt,几乎覆盖了所有常见编程语言。

格式化器默认是禁用的,需要你在 opencode.json 中显式启用。

内置格式化器一览

OpenCode 内置了丰富的格式化器支持,以下是完整列表:

| 格式化器 | 支持扩展名 | 前置要求 |
|---------|-----------|---------|
| prettier | .js, .jsx, .ts, .tsx, .html, .css, .md, .json, .yaml 等 | package.json 中包含 prettier 依赖 |
| biome | .js, .jsx, .ts, .tsx, .html, .css, .md, .json, .yaml 等 | biome.json(c) 配置文件 |
| ruff | .py, .pyi | ruff 命令可用且有配置文件 |
| uv | .py, .pyi | uv 命令可用 |
| gofmt | .go | gofmt 命令可用 |
| rustfmt | .rs | rustfmt 命令可用 |
| cargofmt | .rs | cargo fmt 命令可用 |
| clang-format | .c, .cpp, .h, .hpp, .ino 等 | .clang-format 配置文件 |
| pint | .php | composer.json 中包含 laravel/pint 依赖 |
| dart | .dart | dart 命令可用 |
| shfmt | .sh, .bash | shfmt 命令可用 |
| terraform | .tf, .tfvars | terraform 命令可用 |
| ktlint | .kt, .kts | ktlint 命令可用 |
| rubocop | .rb, .rake, .gemspec, .ru | rubocop 命令可用 |
| mix | .ex, .exs, .eex, .heex, .leex, .neex, .sface | mix 命令可用 |
| nixfmt | .nix | nixfmt 命令可用 |
| zig | .zig, .zon | zig 命令可用 |
| gleam | .gleam | gleam 命令可用 |
| ocamlformat | .ml, .mli | ocamlformat 命令可用和 .ocamlformat 配置 |
| ormolu | .hs | ormolu 命令可用 |
| standardrb | .rb, .rake, .gemspec, .ru | standardrb 命令可用 |
| air | .R | air 命令可用 |
| cljfmt | .clj, .cljs, .cljc, .edn | cljfmt 命令可用 |
| dfmt | .d | dfmt 命令可用 |
| htmlbeautifier | .erb, .html.erb | htmlbeautifier 命令可用 |

当启用格式化器后,OpenCode 会按照扩展名匹配合适的工具。如果项目中有多个格式化器可以处理同一类型文件(例如 Prettier 和 Biome 都能处理 .ts 文件),OpenCode 会按配置顺序尝试,优先使用第一个可用的工具。

启用与配置 Formatters

基本启用

最简单的配置是在 opencode.json 中将 formatter 设置为 true,这会启用所有内置格式化器:

{
  "$schema": "https://opencode.ai/config.json",
  "formatter": true
}

细粒度配置

如果你需要更精细的控制,可以使用对象形式:

{
  "$schema": "https://opencode.ai/config.json",
  "formatter": {}
}

这样内置格式化器仍然启用,但你可以在对象中覆盖特定工具的配置。

禁用全部格式化器

如果因为某些原因需要禁用所有格式化器,设置为 false 即可:

{
  "$schema": "https://opencode.ai/config.json",
  "formatter": false
}

禁用特定格式化器

如果你只想禁用某个格式化器而保留其他,可以设置 disabled 属性:

{
  "$schema": "https://opencode.ai/config.json",
  "formatter": {
    "prettier": {
      "disabled": true
    }
  }
}

自定义格式化器命令

你可以覆盖内置格式化器的命令,或者添加自定义格式化器。每个格式化器配置支持以下属性:

  • command: string[] — 要执行的命令及参数
  • environment: object — 运行时设置的环境变量
  • extensions: string[] — 处理哪些文件扩展名
  • disabled: boolean — 是否禁用该格式化器

#### 覆盖 Prettier 命令

{
  "$schema": "https://opencode.ai/config.json",
  "formatter": {
    "prettier": {
      "command": ["npx", "prettier", "--write", "--single-quote", "$FILE"],
      "environment": {
        "NODE_ENV": "development"
      },
      "extensions": [".js", ".ts", ".jsx", ".tsx"]
    }
  }
}

这里的 $FILE 是占位符,OpenCode 会自动替换为实际的文件路径。

#### 添加自定义格式化器

如果你使用的语言没有内置支持,或者想用自己编写的脚本,可以这样配置:

{
  "$schema": "https://opencode.ai/config.json",
  "formatter": {
    "custom-sql-formatter": {
      "command": ["sql-formatter", "--config", ".sql-formatter.json", "$FILE"],
      "extensions": [".sql"]
    },
    "custom-markdown-formatter": {
      "command": ["deno", "fmt", "$FILE"],
      "extensions": [".md"]
    }
  }
}

工作原理解析

当 OpenCode 完成一次文件写入或编辑操作后,格式化器系统的工作流程如下:

检测文件扩展名:将写入的文件扩展名与所有启用的格式化器进行匹配

查找可用的格式化器:确认所需的命令或配置文件在项目中是否存在

执行格式化命令:运行匹配的格式化器命令,传入文件路径

应用格式化结果:将格式化后的内容写回到原文件

整个过程在后台静默完成,你只会在终端看到最终的、已经格式化好的代码。这意味着你可以专注于审查 AI 生成的逻辑是否正确,而不用操心分号、缩进、引号等风格问题。

多语言项目实战配置

JavaScript/TypeScript 项目

对于前端项目,推荐只启用 Prettier(或 Biome),禁用不需要的格式化器以避免冲突:

{
  "$schema": "https://opencode.ai/config.json",
  "formatter": {
    "biome": {
      "disabled": true
    },
    "prettier": {
      "command": ["npx", "prettier", "--write", "$FILE"]
    }
  }
}

Python 项目

Python 项目推荐使用 Ruff,因为它速度快且功能全面:

{
  "$schema": "https://opencode.ai/config.json",
  "formatter": {
    "ruff": {
      "command": ["ruff", "format", "$FILE"]
    }
  }
}

PHP Laravel 项目

Laravel 项目通常使用 Pint 作为格式化工具:

{
  "$schema": "https://opencode.ai/config.json",
  "formatter": {
    "pint": {
      "command": ["./vendor/bin/pint", "$FILE"]
    }
  }
}

Go 项目

Go 语言的标准格式化工具是 gofmt,配合 goimports 可以获得更好的导入排序:

{
  "$schema": "https://opencode.ai/config.json",
  "formatter": {
    "gofmt": {
      "command": ["gofmt", "-w", "$FILE"]
    }
  }
}

Rust 项目

Rust 项目推荐使用 rustfmt,它会读取项目根目录的 rustfmt.toml 配置:

{
  "$schema": "https://opencode.ai/config.json",
  "formatter": {
    "rustfmt": {
      "command": ["rustfmt", "$FILE"]
    }
  }
}

与编辑器格式化器的配合

需要注意的是,OpenCode Formatters 与你的 VS Code、Cursor 等编辑器的"保存时格式化"功能是独立运行的。最佳实践是:

在编辑器中关闭"保存时自动格式化"(editor.formatOnSave),避免双重格式化造成冲突

让 OpenCode 在写入文件时完成格式化

这样你既享受了 AI 自动格式化的便利,又不会与编辑器行为产生冲突

常见问题

格式化器没有生效怎么办?

检查以下几点:

  • 是否在 opencode.json 中正确启用了 formatter
  • 格式化工具是否已安装并在 PATH 中可用
  • 配置文件(如 .prettierrcruff.toml)是否存在于项目中
  • 文件扩展名是否在格式化器的支持列表中

多个格式化器冲突怎么办?

如果某个文件类型被多个格式化器匹配(例如 .ts 文件同时匹配了 Prettier 和 Biome),OpenCode 会按照配置中出现的顺序优先使用第一个匹配的格式化器。建议只启用一个用于该类型的格式化器,将不需要的设置为 disabled: true

总结

OpenCode Formatters 是一个小而美的功能,它解决了 AI 编程中的一个实际痛点:代码风格一致性。通过简单的 JSON 配置,你可以让 AI 生成的代码自动遵循 Prettier、Ruff、gofmt 等工具定义的规范,无需手动格式化每一段代码。

无论你是在维护单体仓库还是多语言微服务项目,合理配置 Formatters 都能显著提升工作效率,让你专注于代码逻辑本身,而不是格式细节。