ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

Apollo Client 文档工程体系:DocBlock、canonical reference 与 docmodel 生成管线

2026/9/20 19:13:23 拓冰建站 浏览量
Apollo Client 文档工程体系:DocBlock、canonical reference 与 docmodel 生成管线 Apollo Client 文档工程体系DocBlock、canonical reference 与 docmodel 生成管线【免费下载链接】apollo-clientThe industry-leading GraphQL client for TypeScript, JavaScript, React, Vue, Angular, and more. Apollo Client delivers powerful caching, intuitive APIs, and comprehensive developer tools to accelerate your app development.项目地址: https://gitcode.com/gh_mirrors/ap/apollo-client本文基于 Apollo Client 仓库的文档工程说明 documentation.md 展开完整梳理该项目「MDX 文档 源码 DocBlock 双数据源」的组织方式、canonical reference 机制、{inheritDoc}文档继承的构建实现以及npm run docmodel背后的 API Extractor 管线。读完本文你将能够理解 Apollo Client 的 API 参考文档如何从 TypeScript 源码自动生成并在参与贡献时正确编写、引用和更新 DocBlock。文档存放位置docs/ 目录与源码 DocBlock 双数据源Apollo Client 的文档内容分布在两个地方docs/目录存放人撰写的.mdx教程与指南页面其整体结构由 docs/source/_sidebar.yaml 定义。该文件声明了文档侧边栏的完整目录树包括 Core conceptsQueries、Suspense、Fragments、Mutations 等、Caching、Pagination、Local State、Development Testing、Performance、Integrations、Networking 等主章节以及 API Reference 下的 Core / Errors / React / Apollo Link 分组。从源码结构看API Reference 中每一项如useQuery、ApolloClient、HttpLink都对应docs/source/api/下的一个.mdx文件这些页面大量依赖下文介绍的 MDX 组件从 DocBlock 中拉取内容。src/目录中的 DocBlock即 TypeScript 源码里贴在接口、成员、函数上的 JSDoc 注释块。它们是 API 参考页面的真正数据源。这一「双数据源」设计决定了后文所有规则人写的 MDX 是骨架DocBlock 是 API 细节的权威来源。数据源client.api.json 与 canonical reference什么是 canonical referenceDocBlock 之间可以互相引用引用格式形如/** {inheritDoc apollo/client!QueryOptionsDocumentation#query:member} */其中apollo/client!QueryOptionsDocumentation#query:member被称为canonical reference规范引用用于唯一标识一个 DocBlock——即「QueryOptionsDocumentation接口上query这个成员的文档」。这类「文档宿主接口」集中定义在 src/react/types/types.documentation.ts 与 src/utilities/internal/types/DocumentationTypes.ts 中。以types.documentation.ts为例QueryOptionsDocumentation为query、variables、errorPolicy、fetchPolicy、pollInterval、returnPartialData等每个选项都写好了完整描述并带有docGroup标签如docGroup 3. Caching options用于在生成的 API 页面中对选项分组展示。生成全量 DocBlock 累积文件所有 DocBlock 及其 canonical reference 的累积清单位于docs/public/client.api.json。需要强调两点来自文档的明确约束该文件由源码自动生成只能读取、不能手工修改要改文档内容必须修改src/中对应的源文件然后重新生成。docs/public/目录下的所有.json文件同理均为自动生成产物在当前工作区快照中该目录不存在于提交内容中属于构建产物需运行构建流程后生成。npm run docmodel 管线重新生成的命令是npm run docmodel。查看 package.json 中该脚本的定义docmodel: npm run clean node config/build.ts --stepprepareDist --stepaddExports --steptypescript --stepinlineInheritDoc --stepdeprecateInternals node config/apiExtractor.ts --main-only --generate docModel管线分两段第一段构建步骤config/build.ts依次执行prepareDist/addExports/typescript准备dist/产物并编译出类型声明文件inlineInheritDoc将{inheritDoc}注释在构建期展开为实际 DocBlock 文本下一节详述deprecateInternals给内部 API 标注废弃信息。第二段API Extractor 提取由 config/apiExtractor.ts 执行它读取 api-extractor.json 基础配置并结合dist/package.json的exports字段推导入口点--main-only模式下docModel分支会为「全部入口点的组合」生成一份临时entry.d.ts见buildDocEntryPointsconfig/apiExtractor.ts#L79-L97再调用Extractor.invoke生成 docModel JSON即client.api.json。生成 docModel 后脚本还会遍历 JSON 中所有canonicalReference字段收集出完整合法的引用列表写出canonical-references.jsonconfig/apiExtractor.ts#L102-L122。这份清单随后被 ESLint 规则消费用于在提交前校验引用有效性见后文。退出码语义若 Extractor 只有警告没有错误脚本将退出码 50 重置为 0config/apiExtractor.ts#L98-L100即纯警告不阻断流程--generate参数只允许apiReport与docModel两个值传其他值会直接抛错config/apiExtractor.ts#L40-L46。与 docmodel 平行npm run extract-api:only对应 package.json#L93会针对每个导出入口生成.api.md报告文件用于在 CI 中比对公共 API 变更。DocBlock 继承{inheritDoc} 机制原则不重复去引用文档给出的核心原则是DocBlock 不应在其他地方重复已存在的 DocBlock 内容而应使用inheritDoc注解引用。在新增任何文档文本之前应先在 src/react/types/types.documentation.ts 和 src/utilities/internal/types/DocumentationTypes.ts 中检索是否已有现成 DocBlock能引用就引用。构建期展开实现展开工作由构建步骤 config/inlineInheritDoc.ts 完成其流程是先加载一次完整的 ApiModelloadApiModel临时生成入口.d.ts、软链接包根目录、运行一次 API Extractor 得到client.api.json供后续解析引用。用正则匹配注释中的继承指令核心正则config/inlineInheritDoc.ts#L178-L179const inheritDocRegex /\{\s*inheritDoc\s(\S)(?:\s(\{[^}]*\}))?\s*\}(?:\s*$)?/;第一个捕获组是 canonical reference第二个可选捕获组是JSON形式的变量包如{name:useMutation}。解析引用并替换文本getCommentForconfig/inlineInheritDoc.ts#L62-L103通过model.resolveDeclarationReference定位目标 DocBlock 并渲染其文本被继承的 DocBlock 内可以写{{variable}}占位符由传入变量替换。两个严格校验占位符引用了未定义变量、或传入了未被使用的变量都会抛错。若引用无法解析或目标无文档则报错并令进程以非零退出码结束。兜底检查处理完成后若注释中仍残留inheritDoc说明替换失败脚本会警告并置process.exitCode 1config/inlineInheritDoc.ts#L217-L227。该步骤存在的根本原因源码文件头注释有说明API Extractor 的 docModel 生成无法处理诸如interface Foo extends OmitBar, baz {}这类复杂类型的文档继承因此需要先用「扁平化 文本内联」的方式把文档补齐再交给 Extractor 提取。ESLint 侧的引用校验eslint-local-rules/canonical-references.ts 提供两条本地 ESLint 规则在编辑器/CI 阶段就拦截无效引用validInheritDoceslint-local-rules/canonical-references.ts#L9-L68扫描块注释中的inheritDoc ref把ref与docs/public/canonical-references.json的集合比对未知引用报Unknown canonical reference同时把拼错的inheritdoc自动修复为inheritDocfixable: code。validMdxCanonicalReferenceseslint-local-rules/canonical-references.ts#L70-L103校验.mdx文件中 JSX 属性canonicalReference...的值必须是字符串且存在于合法集合中——这保证了 MDX 页面引用的每个 DocBlock 都真实存在。可用的 MDX 组件.mdx文件中可用的组件在 docs/shared/MdxProvidedComponents.ts 中以类型形式声明。与本文主题最相关的几个组件作用关键属性DocBlock按 canonical reference 渲染某个 DocBlock 的各段落canonicalReference必需summary默认true其余段落开关默认falseremarks、example、deprecated、releaseTagremarksCollapsiblecustomOrder自定义段落顺序Example单独渲染example代码块canonicalReference、collapsible、headingLevel、indexFunctionDetails生成「标题 描述 示例 签名 参数表 返回类型」的完整函数文档canonicalReference、displayName覆盖默认标题、headingLevel、parameters/result开关InterfaceDetails渲染接口及其属性表canonicalReference、headingLevel、displayName、customPropertyOrderPropertySignatureTable只渲染属性签名表canonicalReference、idPrefix、customOrder、displayparent/child、genericNamesEnumDetails渲染枚举文档canonicalReference、headingLevelMinVersion标注「该特性仅在某个最小版本起可用」version字符串此外还有排版类组件ExpansionPanel、Tip、Caution、Note、MultiCodeBlock、ManualTuple/ManualTupleItem、Remarks、YouTube、ButtonLink等。其中DocBlock、FunctionDetails等组件的canonicalReference属性正是与canonical-references.json对账的入口与上一节的 MDX ESLint 规则形成闭环。文档写作规范以下规范逐条继承自 documentation.md是撰写或修订文档时的硬性约束。语气Tone文档应采用平易近人、积极、鼓励性的语气做到有帮助、有观点opinionated在易读易跟随的同时给出明确的最佳实践指引。目标读者是各技能层级、不同母语背景的 JavaScript / TypeScript 开发者因此措辞要考虑非英语母语读者的可读性尽量避免嵌套长句和非领域内的高难度词汇。任何情况下不得对读者表现出讽刺、居高临下或轻视。拼写与语法遵循美式英语规范。面向读者时使用主动语态如 You can use theuseQueryhook to fetch data而非 TheuseQueryhook can be used to fetch data描述库自身行为时可以被动语态如 TheuseQueryhook returns an object containing the query result。尽量避免使用 we仅当指代 Apollo Client 团队整体时可用如 We recommend using fragment colocation and data masking.。变更描述绝对禁止引用历史CRITICAL RULE文档只描述库的当前状态禁止出现任何指向旧版本或历史行为的表述。被明确禁止FORBIDDEN的措辞包括previously / previous behaviorhas been restructured / has been changednow takes / now providesin earlier versionsused to be / was changed以及其他任何「过去是什么样」的表述正确做法CORRECT描述事物现在如何工作直接陈述当前行为不拿过去版本做对比地解释当前 API。两条配套规则新增功能可用MinVersion version3.10.0标签包裹标题说明该功能仅在 Apollo Client 3.10.0 及以后版本可用重大版本major引入的功能不应使用MinVersion——因为每个大版本维护一份独立的文档副本当前这份即为 major 版本 4 的文档副本见 _sidebar.yaml 顶部的 v2/v3/v4 版本切换器定义因此对旧版本的引用都可以删除且永远不应出现 since version 4.0, this or that change applied 之类的句子。API 描述偏好有选择余地时描述dataState属性的状态而不是提及partial尽可能具体说明能观察到的networkStatus而非笼统使用loading属性个别场景同时提及两者是有意义的。更新过时的 DocBlock 的标准流程如果发现在docs/public/client.api.json中存在过时或错误的文档在该 JSON 结构中定位最接近的父级fileUrlPath字段得到文档所在的源文件修改该文件中原始的 DocBlock运行npm run docmodel重新生成 JSON再次读取docs/public/client.api.json确认结果。这与前文「JSON 只能读、只能从源码重新生成」的约束完全一致。DocBlock 标签规范用template而非param记录 TypeScript 泛型参数例如template TData - The type of data returned by the queryparam只用于真实函数参数用returns记录返回值用defaultValue记录选项接口中属性的默认值这在 API 参考页面中会被渲染为属性表的默认值列用example提供代码示例供DocBlock example/Example组件展示。小结一次文档修改的完整链路把全文串起来在 Apollo Client 中贡献文档的链路是在 src/ 源码中编写或修改 DocBlock遵循template/param/returns/defaultValue/example规范优先inheritDoc复用 src/react/types/types.documentation.ts 等文档类型中已有内容ESLint 规则eslint-local-rules/canonical-references.ts在本地即校验inheritDoc与 MDXcanonicalReference的合法性npm run docmodel执行构建步骤含 config/inlineInheritDoc.ts 的继承展开后由 config/apiExtractor.ts 生成client.api.json与canonical-references.jsondocs/source/ 下的.mdx页面通过 docs/shared/MdxProvidedComponents.ts 声明的DocBlock、FunctionDetails等组件按 canonical reference 从 JSON 中取内容渲染成最终 API 参考页面全文语气与措辞遵守「只写当前状态、不写历史」的 CRITICAL RULE。掌握这条链路后无论是修复一处过时的 API 描述还是为新增选项补充文档都能在「源码 DocBlock → 构建生成 → MDX 渲染」的正确环节动手而不是去手改自动生成的 JSON。【免费下载链接】apollo-clientThe industry-leading GraphQL client for TypeScript, JavaScript, React, Vue, Angular, and more. Apollo Client delivers powerful caching, intuitive APIs, and comprehensive developer tools to accelerate your app development.项目地址: https://gitcode.com/gh_mirrors/ap/apollo-client创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考