- 后端
- 前端
- 数据分析
- 数据可视化
【免费下载链接】growthbook
Open Source Feature Flags, Experimentation, and Product Analytics
GrowthBook 的官方文档以 Mintlify MDX 页面形式存放于仓库的docs/目录,新增或修改这些页面时,最隐蔽的坑是 YAML frontmatter 中含特殊字符的值解析失败。本文以仓库的文档编写指南 docs.md 为核心,结合校验脚本 scripts/check-docs-frontmatter.mjs、CI 工作流 .github/workflows/docs.yml 与 pre-commit 钩子配置,完整讲清这条规则的由来、判定逻辑与落地方式,读完即可安全地新增或修改docs/下的任意页面。
背景:docs/ 目录使用 Mintlify 托管与部署
GrowthBook 文档站由 Mintlify 负责托管与部署,仓库中的docs/目录只存放源码页面(.mdx与少量.md),站点结构由 docs/docs.json 定义。CI 工作流中对这一点有明确注释(.github/workflows/docs.yml):
# Mintlify hosts/deploys docs via their GitHub App; this job only validates content.也就是说,仓库侧的 CI 工作流只负责内容校验,不承担构建发布。因此,frontmatter 这类"语法层"错误如果不在仓库侧拦住,只能在 Mintlify 侧构建失败后才暴露,排查成本高——这正是仓库为文档专门编写校验脚本并在 CI 与本地提交两个层面强制执行的原因。
核心规则:含"冒号加空格"的 YAML 标量值必须加引号
docs.md 给出的规则只有一条,但非常关键:MDX frontmatter 是 YAML,冒号后紧跟空格(:)会开启一个嵌套映射(nested mapping),因此下面这种写法是非法的:
title: AI Mode: Generate A/B Test Variations With AIYAML 解析器会把AI Mode当作内层键、把Generate A/B Test Variations With AI当作内层值,而不是把整串当作title的字符串值。正确做法是给整个值加引号:
title: "AI Mode: Generate A/B Test Variations With AI"指南进一步说明了两条边界:
- 规则适用于所有标量字段:
description、sidebarTitle与任意其他标量都遵循同一规则; - URL 可以不引号:形如
https://example.com的值中冒号后没有空格,不会触发嵌套映射,直接裸写即可。
除:之外,还有一类容易中招的写法:空格加井号(#)在 YAML 中标记注释的起始,其后的内容会被截断。校验脚本的文件头注释(scripts/check-docs-frontmatter.mjs)明确了两类拦截对象:
/** * Fail if MDX/MD YAML frontmatter uses an unquoted scalar that contains * `: ` (colon + space) or ` #`. YAML treats those as a nested mapping or * a comment, so titles like `AI Mode: Generate…` must be quoted. */校验脚本逐段解析:scripts/check-docs-frontmatter.mjs
这条规则由一个约 120 行的零依赖 Node 脚本强制,脚本本身也是理解规则边界的最准确材料。下面按执行流程逐段说明。
Frontmatter 提取
extractFrontmatter()(scripts/check-docs-frontmatter.mjs#L49-L55)的判定非常严格:
- 文件的第一行必须恰好是
---,否则视为无 frontmatter,整个文件直接跳过; - 从第二行开始寻找下一个
---作为结束边界; - 只解析两个
---之间的行,行号偏移(startLine: 2)用于后续报错时换算真实行号。
这意味着脚本只约束 frontmatter 区块,正文中的 YAML 代码块不受影响。
逐行匹配与判定条件
核心函数findUnquotedYamlIssues()(scripts/check-docs-frontmatter.mjs#L19-L36)对每一行依次做四步判断:
- 跳过空行和注释行:
line.trim()为空或以#开头的行直接略过; - 匹配键值行:使用正则
LINE_RE = /^(\s*)([\w-]+):\s+(.*)$/(scripts/check-docs-frontmatter.mjs#L17),即"可选缩进 + 单词/连字符组成的键 + 冒号 + 空格 + 值"; - 跳过已加引号或结构化值:
isQuotedOrStructured()(scripts/check-docs-frontmatter.mjs#L38-L47)认为以下前缀开头的值安全——"、'、|(块标量)、>(折叠标量)、{(内联映射)、[(内联序列); - 触发检查:剩余裸值若匹配
/: | #/(scripts/check-docs-frontmatter.mjs#L28),记为一个 issue,并记录键名与原文以便给出修复建议。
文件遍历范围
walk()(scripts/check-docs-frontmatter.mjs#L57-L67)递归遍历docs/目录,跳过node_modules与.git,仅处理.mdx和.md两种扩展名。脚本入口处通过REPO_ROOT(脚本位于scripts/下,向上一级)与DOCS_ROOT定位根目录,因此从仓库任意位置运行结果一致。
内置自测用例
selfTest()(scripts/check-docs-frontmatter.mjs#L69-L88)在每次运行前执行 8 组用例,任何一组不符合预期即抛错终止,保证脚本自身不会被静默改坏。这些用例恰好构成了规则的最清晰参考表:
| 输入行 | 预期 issue 数 | 说明 |
|---|---|---|
title: AI Mode: Generate | 1 | 未加引号且含": " |
title: "AI Mode: Generate" | 0 | 双引号包裹,合法 |
title: 'AI Mode: Generate' | 0 | 单引号包裹,合法 |
title: Feature Flags | 0 | 普通值,无触发字符 |
title: Config.yml | 0 | 普通值,无触发字符 |
description: See https://docs.growthbook.io | 0 | URL 冒号后无空格,可裸写 |
description: Foo # truncated | 1 | #会被 YAML 当作注释起始 |
description: "Foo # kept" | 0 | 加引号后内容完整保留 |
输出格式与退出码
main()(scripts/check-docs-frontmatter.mjs#L90-L116)汇总所有 issue 后写入 stderr 并以退出码1结束;无 issue 则静默通过。每条错误包含文件相对路径、行号、原始行,以及脚本替你想好的修复写法(把值重新用双引号包起来),输出形如:
docs/some-page.mdx:2: unquoted YAML value contains ": " or " #". Quote it. title: AI Mode: Generate A/B Test Variations With AI title: "AI Mode: Generate A/B Test Variations With AI"最后两行的建议值取自issue.line中第一个冒号之后的部分(scripts/check-docs-frontmatter.mjs#L102),可直接复制使用。
规则的三处强制点
仓库把这条规则嵌入了本地与 CI 两层防线,这也是 docs.md 末句"CI enforces this withnode scripts/check-docs-frontmatter.mjsin the Docs workflow"的完整展开。
1. GitHub Actions Docs 工作流
.github/workflows/docs.yml 在pull_request与push(main 分支)时触发,且通过paths过滤只在以下文件变化时运行:docs/**、scripts/check-docs-frontmatter.mjs、scripts/check-doclink-registry.mjs、packages/front-end/components/docSections.ts及工作流自身。校验步骤的顺序为(.github/workflows/docs.yml#L34-L50):
- frontmatter 引号检查:
node scripts/check-docs-frontmatter.mjs(Node 24 环境); - 安装 Mintlify CLI:固定版本
mint@4.2.910,注释说明原因是 "mint publishes ~daily and a partial publish breakslatest"——钉住版本避免latest被部分发布污染; - 构建校验:在
docs/目录执行mint validate; - 死链检查:
mint broken-links --check-anchors --check-redirects,同时检查锚点与重定向; - DocLink 注册表检查:
node --disable-warning=MODULE_TYPELESS_PACKAGE_JSON scripts/check-doclink-registry.mjs。
frontmatter 检查放在最前,意味着一个未加引号的 title 会最先、最快失败,不必等待耗时更长的 Mintlify 构建校验。
2. pre-commit 钩子(lint-staged)
根 package.json 的lint-staged配置中,./docs/**/*.{md,mdx}模式的文件在 git commit 时会依次执行prettier --write与node scripts/check-docs-frontmatter.mjs。也就是说,即使不跑 CI,本地提交文档改动时问题也会被拦截在 commit 阶段,开发者能立即看到错误行与修复建议。
3. 仓库 Agent 指令
根 AGENTS.md 在代码质量命令一节中列出了该命令(node scripts/check-docs-frontmatter.mjs # Quote YAML values that contain ": "),并在"详细指引"一节把 docs.md 登记为改动docs/区域前必读的指南。
实操清单:新增或修改 docs/ 页面
结合以上机制,向docs/添加或修改页面时的可靠流程是:
- frontmatter 中任何含
:或#的标量值(title、description、sidebarTitle 等)一律用双引号或单引号包裹;URL 类值(https://...)可以裸写; - 本地运行
node scripts/check-docs-frontmatter.mjs做全量自检——脚本先跑内置自测,再遍历整个docs/目录,即使你只想改一个文件,也建议全量跑一遍确认没有历史遗留问题;正常提交时 lint-staged 也会自动触发该检查; - 提交 PR 后,只要改动落在
docs/**或上述触发路径内,Docs 工作流会自动执行 frontmatter 检查、mint validate、死链检查与 DocLink 注册表检查,全部通过才视为文档改动合格; - 注意根 package.json 中 prettier 对
**/*.mdx配置了embeddedLanguageFormatting: "off",即 Prettier 不会重排 MDX 中内嵌代码块的内容——frontmatter 的引号问题不会由格式化工具替你修,脚本检查是唯一防线,不要依赖pnpm pretty来"顺手"修正它。
小结
GrowthBook 文档侧的这条规范把"YAML frontmatter 中未加引号的:与#会导致解析错误"这一条语言层面的规则,用零依赖脚本(scripts/check-docs-frontmatter.mjs)转化为可执行的机器检查,并接入 Docs CI 工作流(.github/workflows/docs.yml)与 lint-staged 提交钩子(package.json)形成双层强制,同时脚本内置自测保证检查器自身的行为稳定。对贡献者而言,只需记住 docs.md 中的核心规则并养成"含特殊字符的 frontmatter 值加引号"的习惯,文档改动即可顺利通过仓库侧的全部校验。
- 后端
- 前端
- 数据分析
- 数据可视化
【免费下载链接】growthbook
Open Source Feature Flags, Experimentation, and Product Analytics
相关推荐
Trigger.dev 文档编写规范:基于 Mintlify MDX 的写作规则与实战指南
Trigger.dev 文档编写规范:基于 Mintlify MDX 的写作规则与实战指南 本文围绕 Trigger.dev 开源仓库中的 .claude/ru
AI Agent后端任务调度开发工具可观测性AI 应用Rivet Actors 内容 Frontmatter 规范:为官方文档与博客编写可校验的 YAML 元数据
Rivet Actors 内容 Frontmatter 规范:为官方文档与博客编写可校验的 YAML 元数据 导读 本文基于仓库内的《Content front
后端AI Agent人工智能流程编排WebSocketHyperframes 文档工程规范:面向 Mintlify 的 MDX 写作与维护标准
Hyperframes 文档工程规范:面向 Mintlify 的 MDX 写作与维护标准 本文是 Hyperframes 开源仓库内文档编写、结构与维护的工程标
音视频视频AI 技能
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考