☰
pollinations 仓库分支级代码格式化实战:用 Biome Skill 保持代码风格与 CI 一致
2026/10/13 6:31:30 网站建设 项目流程
  • AI 应用
  • 媒体生成
  • 后端
  • 前端

【免费下载链接】pollinations

Your Friendly Open-Source Gen-AI Platform

项目地址:https://gitcode.com/gh_mirrors/po/pollinations
点击查看免费下载

导读

pollinations 是一个大型 TypeScript/JavaScript 单体仓库(monorepo),横跨enter.pollinations.ai、gen.pollinations.ai、packages/sdk、packages/ui等多个工作区。为了让海量代码在提交与提 PR 前保持统一格式,仓库维护了一个名为code-formatting的 Claude Code Skill:一条命令即可对当前分支相对基线分支(默认main)改动过的所有 JS/TS/JSON 文件执行 Biome 格式化。读完本文,你将掌握该 Skill 的完整用法、底层脚本原理、biome.jsonc配置每一项的含义,以及它与ci-pull-request-checks.ymlCI 工作流如何联动,从而在自己的分支上先一步通过 CI 的格式门禁。

一、Skill 概览:一条命令完成格式化

Skill 的入口文档位于 .claude/skills/code-formatting/SKILL.md。它的 frontmatter 定义了触发语义:

  • name: code-formatting
  • description: Format code on the current branch using Biome. Use when asked to format, lint, or clean up code before committing or creating a PR.

也就是说,只要向 Claude 提出"format / lint / clean up code"之类的请求,Skill 就会被触发,把当前分支上改动过的代码用 Biome 格式化,而不是对整个代码库做全局重排——这既避免了海量无关 diff,也保证了改动的可审查性。

快速使用

在仓库根目录执行:

.claude/skills/code-formatting/scripts/format-branch.sh

该命令会格式化所有与main分支相比发生变更的.js、.ts、.jsx、.tsx、.json、.jsonc文件。

指定自定义基线分支

如果当前分支是从develop(或其他分支)切出的,可以把它作为参数传入:

.claude/skills/code-formatting/scripts/format-branch.sh develop

这样"改动文件"的比对基准就从默认的main切换为你指定的分支。

二、脚本原理拆解:format-branch.sh 做了什么

Skill 的核心逻辑全部封装在 format-branch.sh 这个 bash 脚本中,全文不到 30 行。其流程与文档中 "What It Does" 的四步一一对应:

  1. 找到当前分支相对基线分支改动过的文件;
  2. 过滤出 JS/TS/JSON 类型文件;
  3. 对这些文件运行npx biome check --write;
  4. 使用与ci-pull-request-checks.yml相同的配置。

逐行解读

#!/bin/bash set -e BASE_BRANCH="${1:-main}" # 基线分支,默认 main FILES=$(git diff --name-only "$BASE_BRANCH"...HEAD | grep -E '\.(js|ts|jsx|tsx|json|jsonc)$' || true)
  • set -e:任一命令失败立即退出,避免"格式化中途出错但脚本继续"的假成功;
  • git diff --name-only "$BASE_BRANCH"...HEAD:三连点...表示取HEAD相对BASE_BRANCH与HEAD共同祖先之间的差异,也就是只列出当前分支新增的提交所改动的文件,天然排除了基线分支上已有的历史改动;
  • grep -E '\.(js|ts|jsx|tsx|json|jsonc)$':把改动文件限定到 Biome 能处理的六类扩展名;|| true保证没有匹配时管道不会触发set -e退出。
if [ -z "$FILES" ]; then echo "✅ No JS/TS/JSON files changed on this branch" exit 0 fi echo "$FILES" | xargs npx biome check --write
  • 若当前分支没有 JS/TS/JSON 改动(例如纯文档分支),脚本直接成功退出,不会空跑 Biome;
  • 否则把所有改动文件一次性传给npx biome check --write:--write让 Biome 以"安全修复"模式直接改写文件,包括自动格式化、应用可安全自动修复的 lint 规则。

需要说明的是,format-branch.sh内部使用的git diff ... | grep ...是"简化版"过滤,它没有像 CI 那样排除node_modules、dist、package-lock.json等路径(详见下文第四节)。不过在仓库实际使用中,提交到版本库的依赖产物很少,影响有限;若需要更严格的过滤,可以直接使用仓库根 package.json 中预置的format:changed脚本(见第五节)。

三、与 CI 完全对齐:ci-pull-request-checks.yml 的格式门禁

Skill 文档强调脚本"Uses same settings as theci-pull-request-checks.ymlCI workflow",这不是一句空话。查看 .github/workflows/ci-pull-request-checks.yml 中的lintjob,其做法与本地脚本如出一辙:

- name: Get changed files run: | FILES=$(git diff --diff-filter=d --name-only HEAD^1 HEAD | grep -E '\.(js|ts|jsx|tsx|json|jsonc)$' | grep -v -E '(node_modules|dist|build|\.next|\.cache|out|package-lock\.json|secrets)/' | grep -v 'package-lock\.json$' || true)
  • CI 用git diff --diff-filter=d HEAD^1 HEAD对比 PR 合并提交与其第一父提交(基线分支顶端),--diff-filter=d剔除被删除的文件;
  • 过滤规则与本地脚本相同的六类扩展名,并额外排除node_modules、dist、build、.next、.cache、out、package-lock.json、secrets等路径——这正是biome.jsonc中files.excludes的镜像(详见第四节);
  • 随后运行npx biome check --write --no-errors-on-unmatched(--no-errors-on-unmatched保证文件列表为空时不会报错)。

真正的门禁在下一步:

- name: Check for formatting changes run: | if [[ -n $(git status --porcelain) ]]; then echo "❌ Biome found formatting issues. Run 'npm run format' locally." git diff exit 1 fi

即:CI 先以--write自动修复,再检查git status --porcelain是否还有未提交的改动。只要本地格式化不彻底,CI 就会失败并打印 diff 提示。这正是本地先跑format-branch.sh的价值——在本地把改动格式化到与 CI 完全相同的状态,就能一次通过。此外该 workflow 末尾还有一个gatejob,聚合lint、enter、gen、website四个 job 的结果作为 main 分支规则集要求的状态检查,任何格式问题都会阻断合并。

四、根因解读:biome.jsonc 的每一项配置

无论是本地脚本还是 CI,Biome 的裁决标准都来自仓库根目录的 biome.jsonc。这是格式化的"唯一事实来源",理解它才能真正理解"什么会被改、什么会被跳过"。

4.1 Formatter 与 JavaScript 风格

{ "formatter": { "indentStyle": "space", "indentWidth": 4 }, "javascript": { "formatter": { "quoteProperties": "preserve", "quoteStyle": "double" } } }
  • 缩进:使用空格而非 Tab,宽度为 4。这是 pollinations 全仓库的统一缩进规范,与许多前端项目默认的 2 空格不同,直接由 Biome 强制保证;
  • 引号:字符串统一使用双引号(quoteStyle: "double");
  • 对象属性名:quoteProperties: "preserve"表示不改写"可省略引号的属性名是否带引号"的现状,避免产生无意义 diff。

4.2 Linter 规则

"linter": { "enabled": true, "rules": { "complexity": { "useLiteralKeys": "off", "noBannedTypes": "off" }, "security": { "noDangerouslySetInnerHtml": "off" } } }

enabled: true意味着biome check不只是格式化,还会跑 lint 检查。三条显式关闭的规则说明了项目的取舍:

  • useLiteralKeys(应使用字面量键访问对象属性)关闭:允许obj["dynamic-key"]这类带变量的访问模式,避免过度约束业务代码;
  • noBannedTypes(禁止使用String/Number等包装类型)关闭:允许在代码中使用这些类型;
  • noDangerouslySetInnerHtml(React 禁止直接注入 HTML)关闭:这是面向 UI 层(packages/ui、apps/下有大量 React 应用)的必要豁免,仓库允许在受控场景下使用dangerouslySetInnerHTML。

4.3 files.includes / excludes:界定 Biome 的作用范围

"files": { "includes": ["**"], "excludes": [ ".github/**", "!**/node_modules/**", "!**/secrets/**", "!**/dist/**", "!**/build/**", "!**/.next/**", "!**/.cache/**", "!**/out/**", "!**/worker-configuration.d.ts", "!**/worker-runtime.d.ts", "!**/worker-bindings.d.ts", "!**/better-auth.ts", "!**/routeTree.gen.ts", "!operations/quest-dashboard/assets/bundle.js", "!**/*.css", "!**/*.yml", "!**/*.md", "!packages/ui/src/licenses/**" ] }

每条排除规则背后都有明确理由(配置中已附注释):

排除项原因
.github/**GitHub Actions 工作流文件保持原样
node_modules依赖产物,不该格式化
secrets/**SOPS 加密的密钥文件:重新格式化会破坏加密 MAC 校验
dist/build/.next/.cache/out构建产物
worker-configuration.d.ts等*.d.ts、better-auth.ts、routeTree.gen.ts、quest-dashboard 的bundle.js自动生成文件,格式化会与生成器输出冲突
*.cssBiome 尚不支持 Tailwind v4 语法
*.yml/*.mdBiome 不原生格式化 YAML 与 Markdown
packages/ui/src/licenses/**字体 OFL 许可文本必须逐字分发,不得改动

4.4 overrides 与 CSS/JSON 开关

  • overrides针对apps/chat/**单独放宽了一组规则:关闭a11y下的noSvgWithoutTitle、useButtonType、noLabelWithoutControl等 7 条无障碍规则,以及suspicious.noArrayIndexKey、correctness.useExhaustiveDependencies等——这是对历史遗留 UI 代码的务实豁免,说明仓库允许"按目录差异化配置";
  • css与json的 formatter/linter 均显式enabled: false:JSON 文件由其他工具管理,CSS 因 Tailwind v4 语法问题被整体跳过。

这些排除规则解释了为什么文档会说"只格式化改动文件"——即便某次改动涉及.css或.md,它们也不会进入 Biome 的处理范围。

五、配套入口:npm run format:changed 与 Claude Command

除了 Skill 脚本,仓库还提供了两个等效入口,适用于不同习惯的开发者。

5.1 根目录 npm script

package.json 中预置了format:changed:

"format:changed": "git diff --diff-filter=d --name-only origin/main | grep -E '\\.(js|ts|jsx|tsx|json|jsonc)$' | grep -v -E '(node_modules|dist|build|\\.next|\\.cache|out)/' | xargs npx biome check --write"

与 Skill 脚本相比,它有三个差异:

  • 基线固定为origin/main(远程 main),适合本地分支已落后于远端时的场景;
  • 增加--diff-filter=d,跳过被删除的文件;
  • 额外过滤node_modules、dist等目录,与 CI 的过滤逻辑更接近。

在仓库中执行npm run format:changed即可完成同样的分支级格式化。

5.2 Claude Command:format.md

.claude/commands/format.md 提供了面向 Claude 交互的等价命令,且覆盖了"未暂存"与"已暂存"两种状态:

# 未暂存的改动 git diff --name-only HEAD | grep -E '\.(js|ts|jsx|tsx)$' | xargs -r npx biome check --write # 已暂存的改动(staged) git diff --cached --name-only | grep -E '\.(js|ts|jsx|tsx)$' | xargs -r npx biome check --write

注意这里的扩展名过滤只包含js|ts|jsx|tsx四种(不含 json/jsonc),且针对的是HEAD之前的全部改动而非分支差异——适合"改完随手一跑"的轻量场景,与 Skill 的"分支级"定位互补。

六、在项目工作流中的位置:从 AGENTS.md 到 Quest 检查清单

这个 Skill 并非孤立工具,而是 pollinations 开发纪律的一环,仓库多处文档都引用了同一套 Biome 约定:

  • AGENTS.md 的 "Code Style & Workflow" 一节明确要求:Run npx biome check --write <file> after edits and before commits.,并把 Skill 维护在.claude/skills/下、通过.agents/skills/的相对目录链接暴露给 Codex;
  • 模型管理技能文档 repository-and-local-testing.md 同样要求提交前运行npx biome check --write <changed-files>;
  • 社区 Quest 的提交规范(.github/ISSUE_TEMPLATE/quest.yml)把"已对改动文件运行npx biome check --write"列为 PR 检查清单的必选项;
  • 子包也沿用同样配置,例如 packages/polli-cli/package.json 的lint脚本即biome check --write src/。

由此可见,无论你是直接开发者、提交 Quest 的社区成员,还是驱动 Claude/Codex 完成编码任务的 Agent,"提交前跑一次分支级 Biome 格式化"都是统一的验收前提。

七、使用注意事项与排障建议

综合 Skill 文档的 "Notes" 与源码实现,实际使用时有几点需要留意:

  1. 必须在仓库根目录运行:脚本依赖git diff的仓库级上下文,且npx biome需要能解析到根目录的biome.jsonc与 devDependencies;
  2. 依赖 Node.js / npx:仓库在 package.json 中将@biomejs/biome声明为^2.3.10的 devDependency,请确保已执行过npm install;
  3. 只格式化改动文件,不重排整个代码库:这是设计意图——避免在 PR 中夹带与功能无关的全量 diff,也让 Code Review 聚焦真实改动;
  4. 基线分支可定制:从develop等分支切出的分支,记得用format-branch.sh develop或调整format:changed的基线,否则会把基线分支自身未格式化的历史改动一并卷入;
  5. 与 CI 的判定标准完全一致:本地通过 ≠ 万事大吉,CI 还会用git status --porcelain二次校验。因此本地跑完脚本后建议顺手git status确认没有残留未提交的格式化改动,再提交即可;
  6. 改动的文件类型不在范围内时脚本会安静退出:例如只改了.css/.md/.yml的分支会直接输出 "No JS/TS/JSON files changed" 并成功退出,这是正常行为,因为这类文件本就不在 Biome 的处理范围内。

结语

code-formattingSkill 是 pollinations 仓库"提交前格式化"这一工程纪律的最小落地单元:一条脚本、一份biome.jsonc、一个 CI 门禁,三者共用同一套规则,形成"本地预检 → CI 复核 → 合并放行"的闭环。理解其脚本逻辑与配置意图后,你不仅能在 pollinations 的任意分支上规范地提交代码,也能把这套"分支级、配置驱动、与 CI 对齐"的格式化思路迁移到自己的 Biome 项目中——先读biome.jsonc定规矩,再用脚本把改动圈定在分支内,最后让 CI 兜底验证。

  • AI 应用
  • 媒体生成
  • 后端
  • 前端

【免费下载链接】pollinations

Your Friendly Open-Source Gen-AI Platform

项目地址:https://gitcode.com/gh_mirrors/po/pollinations
点击查看免费下载

相关推荐

上一篇:Audacity技术架构深度解析:从核心原理到高级应用
下一篇:Tectonic `-X build` 命令详解:基于 Tectonic.toml 的项目化文档构建

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

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询