首页
/ Backstage TechDocs FAQ 权威解读:MkDocs 生成机制、实体注解与编辑反馈配置实战

Backstage TechDocs FAQ 权威解读:MkDocs 生成机制、实体注解与编辑反馈配置实战

2026-09-09 20:56:04作者:冯爽妲Honey

本篇技术指南基于 Backstage 仓库中 docs/features/techdocs/FAQ.md 展开,系统解答 TechDocs 使用中最常见的六类问题:静态站点生成器选型、mkdocs-techdocs-core 插件职责、Markdown 之外的格式支持、backstage.io/techdocs-ref 注解在外部构建模式下的行为、backstage.io/techdocs-entity 注解的重定向机制,以及如何在文档页面启用"编辑本页/反馈"按钮。读完本文,你将能理清 TechDocs 的生成技术栈与构建流程,并能在自己的 catalog-info.yamlmkdocs.ymlapp-config.yaml 中正确完成对应配置。

TechDocs 使用什么静态站点生成器?

TechDocs 底层使用 MkDocs 将项目文档从 Markdown 源码构建成站点。MkDocs 是一个面向项目文档的快速、简单的静态站点生成器,由 Python 生态驱动,其生态中丰富的插件和主题是 TechDocs 阅读体验的重要来源。

对于使用 techdocs-container(即默认的 spotify/techdocs Docker 镜像)构建的文档,站点采用 MkDocs 的 Material Thememkdocs-material)。这一主题提供了现代、响应式的阅读界面,也是 TechDocs 默认文档站点的外观基础。

在仓库的 app-config.yaml 中可以看到 TechDocs 生成器的默认运行方式:

techdocs:
  builder: 'local' # Alternatives - 'external'
  generator:
    runIn: 'docker'
  publisher:
    type: 'local' # Alternatives - 'googleGcs' or 'awsS3' or 'azureBlobStorage' or 'openStackSwift'

这里的 techdocs.generator.runIn: 'docker' 表示生成文档时会拉起 techdocs-container Docker 镜像来执行 MkDocs,其完整配置项说明见 docs/features/techdocs/configuration.md。若你在自定义 Docker 环境中运行 Backstage、希望避免"Docker 中的 Docker"(Docker-in-Docker)问题,可将该值改为 'local',前提是本机已安装好 MkDocs 及其所需依赖。

mkdocs-techdocs-core 插件是什么?

mkdocs-techdocs-core 是一个 MkDocs 插件包,它扮演"包装器"(wrapper)的角色:内部聚合了多个 MkDocs 插件(例如 MkDocs Monorepo Plugin),并精选了一批 TechDocs 官方支持的 Python Markdown 扩展。其目的是让用户开箱即用地获得 TechDocs 官方推荐的 Markdown 渲染能力,而无需在每份 mkdocs.yml 里手工声明一长串插件和扩展。

mkdocsPatchers.ts 中可以看到 TechDocs 在生成前对 mkdocs.yml 的自动修补逻辑:

export const patchMkdocsYmlWithPlugins = async (
  mkdocsYmlPath: string,
  logger: LoggerService,
  defaultPlugins: string[] = ['techdocs-core'],
) => {

默认情况下 techdocs-core 会被自动注入到每一份 mkdocs.yml;如果该文件未声明 plugins,则直接写入默认插件列表;如果已声明,则会逐项检查并补充缺失的默认插件。若想改变这一行为,可以通过 techdocs.generator.mkdocs.defaultPlugins 配置全局默认插件,或用 techdocs.generator.mkdocs.omitTechdocsCorePlugin: true 完全关闭自动注入(详见 configuration.md 中的 MkDocs Configuration 一节)。注意:手动指定的插件必须已经安装在你使用的 Docker 镜像或本地环境中。

TechDocs 是否支持 Markdown 之外的文件格式(如 RST、AsciiDoc)?

目前不支持。 由于 TechDocs 当前通过 MkDocs 从源码生成文档,因此源文件必须为 Markdown 格式。FAQ 明确说明,未来有计划支持其他静态站点生成器(SSG),届时才有望支持 RST、AsciiDoc 等其他格式。因此现阶段编写 TechDocs 文档时,应统一使用 Markdown,并配合 MkDocs 的插件生态(docs_dirnav 等)组织站点结构。

使用外部构建与存储时,backstage.io/techdocs-ref 应该取什么值?

backstage.io/techdocs-ref 注解的值在 TechDocs 的构建过程中会被使用。但当你把 techdocs.builderapp-config.yaml 中设为 'external' 时,这个注解的值不会被使用——因为此时文档由仓库的 CI/CD 等外部流程构建并发布,techdocs-backend 只负责从存储读取,不再触发生成。

不过,该注解仍然必须存在于实体描述文件(如 catalog-info.yaml)中,其作用是让 Backstage 知道该实体启用了 TechDocs。

该注解的取值语义定义在 well-known-annotations.md

metadata:
  annotations:
    backstage.io/techdocs-ref: dir:.

它告知 TechDocs 文档源内容存放的位置,最常见的写法是相对 catalog-info.yaml 所在位置、能找到 mkdocs.yml 的路径;在文档与实体源码不在一起的少数场景下,也可以写成绝对 URL 形式的 location reference,例如 url:https://github.com/backstage/backstage/tree/master

从源码看,注解的解析逻辑在 helpers.tsparseReferenceAnnotation 中:它读取实体注解并以 location ref 格式拆分为 typetarget。而 dir 类型的相对引用会通过 transformDirLocationhelpers.ts)基于实体的来源位置解析为绝对地址:实体来自 url 位置时,用 SCM 集成的 resolveUrl 拼出目标子目录的完整 URL;实体来自 file 位置时,则解析为文件系统上的绝对目录。这正好解释了 FAQ 中"值在外部构建模式下不被使用"的细节:'external' 模式下没有本地生成环节,自然不需要去定位文档源;注解只作为 TechDocs 的启用标志存在。

'local''external' 两种构建策略的本质区别

FAQ 中"外部构建"的行为,可以结合 router.ts/sync/:namespace/:kind/:name 路由的源码来理解:

  • techdocs.builder: 'local'(默认,即"Basic"架构):当用户打开 TechDocs 页面时,techdocs-backend 会尝试现场生成文档、发布到存储并展示,此时 backstage.io/techdocs-ref 注解的值参与定位文档源;
  • techdocs.builder: 'external'(推荐,即"Recommended"架构):techdocs-backend 只负责从存储获取文档,不会尝试生成与发布,backstage.io/techdocs-ref 的值不再被用于构建。

路由中通过注入的 docsBuildStrategy.shouldBuild({ entity }) 决定是否触发构建;默认策略 DefaultDocsBuildStrategyDefaultDocsBuildStrategy.ts)读取 techdocs.builder 配置实现上述两种行为,同时允许自定义策略基于实体属性实现更复杂的逻辑。仓库根目录的 app-config.yaml 中默认使用 builder: 'local' 并注释了 'external' 作为备选。

访问带 backstage.io/techdocs-entity 注解的实体时会发生什么?

当你在浏览器中访问形如 docs/{namespace}/{kind}/{name} 的 TechDocs URL,且目标实体带有 backstage.io/techdocs-entity 注解(而非 backstage.io/techdocs-ref)时,Backstage 会重定向到该注解值所引用实体的 TechDocs 页面。

该注解的语义定义于 well-known-annotations.md

metadata:
  annotations:
    backstage.io/techdocs-entity: component:default/example

其值指向"拥有这些 TechDocs"的外部实体。典型场景是:多个组件共享同一个仓库(通常是 monorepo)和同一份文档位置,通过该注解让多个组件引用同一份 TechDocs,既避免重复构建,也无需在多个页面重复维护文档副本。与之配套的 backstage.io/techdocs-entity-path 注解(well-known-annotations.md)则允许指定组件文档在外部实体 TechDocs 中的子路径,实现"深链接"(deep linking),而不仅仅指向外部实体文档的根目录。

前端重定向的具体实现位于 useExternalRedirect.ts:页面加载时通过 catalog API 读取实体,若发现存在 TECHDOCS_EXTERNAL_ANNOTATION(即 backstage.io/techdocs-entity)注解,就调用 buildTechDocsURL 构造目标实体的 TechDocs URL,并通过 navigate(..., { replace: true }) 完成跳转。钩子还利用 checkedEntityRef 记录已检查过的实体,避免在同一个实体文档内浏览子页面时反复触发重定向检查与整页加载动画。对应测试见 useExternalRedirect.test.tsx,其中覆盖了 techdocs-entity-path 深链接场景与注解为空的情况。

如何让用户对 TechDocs 页面提出修改建议或反馈?

对于源码托管在 GitHub 或 GitLab 的 TechDocs 站点,可以启用"编辑本页"(edit this page)和"反馈"(leave feedback)按钮。要做到这一点,需要在 mkdocs.yml 中按 MkDocs 官方配置规范提供 repo_urledit_uri 两个配置项。

值得注意的一个自动化行为:即使你的 mkdocs.yml 里没有写 repo_url / edit_uri,TechDocs 生成器也可能会替你补上。在 mkdocsPatchers.tspatchMkdocsYmlPreBuild 中,生成器会检查 mkdocs.yml 是否缺少这两个键,若缺失则根据实体的 backstage.io/techdocs-ref 位置注解推导仓库 URL 并写入:

if (!('repo_url' in mkdocsYml) || !('edit_uri' in mkdocsYml)) {
  const result = getRepoUrlFromLocationAnnotation(
    parsedLocationAnnotation,
    scmIntegrations,
    mkdocsYml.docs_dir,
  );
  if (result.repo_url || result.edit_uri) {
    mkdocsYml.repo_url = mkdocsYml.repo_url || result.repo_url;
    mkdocsYml.edit_uri = mkdocsYml.edit_uri || result.edit_uri;
    ...
  }
}

不过 FAQ 强调:如果源码托管 URL 的主机名中不包含 githubgitlab(例如自托管的 GitHub Enterprise / GitLab 实例,或其他 SCM),还需要在 app-config.yaml 中为源码托管方添加一条 integrations 配置,其中只需提供 host即可。例如仓库根目录 app-config.yaml 中已有的 GitHub / GitLab 集成写法:

integrations:
  github:
    - host: github.com
      token: ${GITHUB_TOKEN}
  gitlab:
    - host: gitlab.com
      token: ${GITLAB_TOKEN}

这条配置让 TechDocs 生成器在推导 repo_url / edit_uri 时能够识别并正确处理你的源码托管主机,从而保证编辑/反馈按钮的链接可正常工作。若你手动在 mkdocs.yml 中显式设置过 repo_url / edit_uri,生成器会保留原值而不覆盖(见上方源码中 mkdocsYml.repo_url || result.repo_url 的保留逻辑)。

小结:FAQ 之外,值得留意的相关配置

FAQ 的每个回答都直接关联到 TechDocs 的配置与注解体系。为便于读者继续深入,这里汇总相关仓库资料:

只要理解了"MkDocs 生成、techdocs-core 聚合插件、Markdown 为唯一源码格式"这条技术主线,再配合 backstage.io/techdocs-refbackstage.io/techdocs-entity 的注解语义,以及 mkdocs.yml + app-config.yaml 的反馈按钮配置,你就能准确预判 TechDocs 在各类部署形态下的实际行为,并在排查"文档不构建""编辑按钮不显示""多组件共享文档"等问题时快速定位根因。

登录后查看全文
热门项目推荐
相关项目推荐

项目优选

收起
kernelkernel
deepin linux kernel
C
33
18
docsdocs
暂无描述
Markdown
900
5.83 K
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.14 K
2.76 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
860
1.35 K
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
927
1.85 K
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.94 K
1.02 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
533
603
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.37 K
1.46 K
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
548
396
cann-learning-hubcann-learning-hub
CANN 学习中心仓,支持在线互动运行、边学边练,提供教程、示例与优化方案,一站式助力昇腾开发者快速上手。
Jupyter Notebook
1.04 K
527