关于 creating-backstage-plugin
这是用于在 Backstage 仓库中规划并创建插件的技能,面向 Backstage 开发者。它指导选择包模板和后续模式,并要求确认计划后再执行脚手架流程。
主要功能
- 01记录插件需求并制定计划
- 02为插件包选择模板
- 03处理前后端关联插件组
- 04脚手架创建前征求确认
- 05应用创建后的相关模式
- 06验证生成的包目录
适用场景
- 01根据描述创建 Backstage 插件
- 02规划带专属后端的插件
- 03添加前端或后端插件模块
- 04创建后应用标准模式
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ vinzscam/ backstage-skills --skill creating-backstage-plugin安装后在 Claude Code 中输入/creating-backstage-plugin确认已加载。
附带文件references/intent-detection.mdreferences/templates.md
详细介绍
创建 Backstage 插件
何时使用此技能
用户想在 Backstage 仓库中启动一个新插件。可能是:
- 他们用自由文本描述了插件(“我想要一个列出我的群组的前端插件”)
- 或者他们只是泛泛地提出需求(“搭建一个新插件”),此时你应该询问他们想要什么
流程
始终按顺序执行以下步骤。第 3 步中用户确认计划之前,不要运行 yarn new。
1. 了解意图
如果用户已经描述了插件,就解析描述。否则,只问一个问题:
“你想要什么类型的插件?它应该实现什么功能?”
2. 将意图解析为计划
将用户的描述映射到:
- packages: 一个或多个软件包脚手架。大多数插件只有一个软件包,但互联插件(前端调用专用后端的插件)需要三个:一个
frontend-plugin、一个backend-plugin和一个用于共享类型的plugin-common-library。有关何时建议采用这种方案,请参阅下文的“互联插件组合”。 - template(每个软件包):9 个受支持模板之一(完整列表和选择规则请参阅
references/templates.md)。 - id(每个软件包):采用 kebab-case。对于互联插件组合,三个 id 共享一个基础名称(例如
jira+jira-backend+jira-common)。 - patterns(每个软件包):脚手架搭建完成后要调用哪些模式技能。请参阅
references/intent-detection.md中的关键词 → 模式启发规则。
互联插件组合
当用户描述的插件同时包含 UI 界面和专用后端时(例如,“一个显示项目信息的 Jira 插件”→ 需要后端代理 Jira API 调用,并需要前端呈现结果),建议使用由 3 个软件包组成的方案,而不是单个模板:
| 软件包 | 模板 | 用途 |
|---|---|---|
<id> | frontend-plugin | UI |
<id>-backend | backend-plugin | 后端路由;与上游系统通信 |
<id>-common | plugin-common-library | 两端共用的 TypeScript 类型(请求/响应接口、领域模型) |
触发信号(满足任一项 → 建议采用由 3 个软件包组成的方案):
- 插件描述提到需要经过身份验证或在服务端进行调用的外部系统(Jira、ServiceNow、PagerDuty、未向浏览器公开的内部 API)
- 用户描述中提到“显示 中的 X 的页面”,且 X 需要后端计算、机密信息,或不适合放在客户端处理的分页/聚合
- 用户明确要求“前端和后端”,或同时提到这两部分
以下情况不要建议采用 3 个软件包的方案:
- 插件只读取已安装的 Backstage 后端(catalog、scaffolder 等)提供的数据——现有服务引用已涵盖这些,无需自定义后端
- 插件纯粹用于展示(表单、计算器、静态数据仪表盘)
建议采用由 3 个软件包组成的方案时,请在第 3 步的确认消息中列出全部三个软件包,以便用户修改方案(例如,“其实我只需要前端,后端已经存在”)。如果用户已经有其中一个软件包,只搭建缺少的软件包。
3. 向用户确认
按照以下格式打印结构化摘要,并等待用户明确批准:
I'll scaffold a `<template>` named `<id>` and wire up:
- <pattern 1 description>
- <pattern 2 description>
Sound right, or want to adjust?
如果用户希望修改,请调整方案并再次确认。
4. 运行 yarn new
确认后,从仓库根目录为计划中的每个包运行命令。
单包场景(插件、库):
yarn new --select <template> --option pluginId=<id>
模块场景(backend-plugin-module、frontend-plugin-module)——模块需要宿主插件 ID 和模块 ID:
yarn new --select backend-plugin-module --option pluginId=<host-plugin> --option moduleId=<module-id>
例如,目录处理器模块:
yarn new --select backend-plugin-module --option pluginId=catalog --option moduleId=my-processor
这会生成 plugins/catalog-backend-module-my-processor。
关联插件集场景——按顺序运行三条命令(先运行 -common,这样其他包才能依赖它):
yarn new --select plugin-common-library --option pluginId=<id>-common
yarn new --select backend-plugin --option pluginId=<id>
yarn new --select frontend-plugin --option pluginId=<id>
注意:yarn new --select backend-plugin --option pluginId=<id> 会生成 plugins/<id>-backend(模板会添加 -backend 后缀)。前端会生成 plugins/<id>。通用包会生成 plugins/<id>-common。
每次运行 yarn new 后,验证目录:
ls plugins/<id-or-suffix>
如果缺少任何目录,请停止操作并向用户说明错误。
5. 脚手架生成后应用模式
对于计划中的每种模式,使用 Skill 工具调用对应的模式技能。传入新插件 ID,并说明这是一次脚手架生成后的调用。每个模式技能的参考资料中都有一个“脚手架生成后的用法”部分,其中注明了文件和插入位置。
前端模板(frontend-plugin、frontend-plugin-module):
using-backstage-frontend-system——始终调用。配置规范的 NFS 结构(src/routes.ts、使用createFrontendPlugin的src/plugin.tsx、一个示例PageBlueprint)。using-backstage-ui——始终调用。将脚手架可能生成的 MUI 导入和样式替换为@backstage/ui对应内容,并使用 BUI 令牌的 CSS 模块。- 如果需求涉及目录数据,则以(前端模式)调用
using-backstage-catalog。 - 如果需求涉及当前用户,则调用
using-backstage-identity。 - 如果需求描述脚手架表单字段 /
ui:field/ 自定义字段扩展,则为frontend-plugin-module调用creating-backstage-scaffolder-field。 - 如果需求描述目录实体页面上的卡片或选项卡(“在组件页面上显示 X”“为 Y 添加卡片”“实体页面上的选项卡”),则为
frontend-plugin-module调用creating-backstage-entity-page-extension。 - 如果需求描述需要通过权限限制 UI(“只有管理员能看到……”“需要权限才能……”“除非……否则隐藏此按钮”),则以(前端模式)调用
using-backstage-permissions。
前端库(plugin-web-library):
using-backstage-ui——始终调用。
后端模板(backend-plugin、backend-plugin-module):
using-backstage-backend-system——始终调用。配置规范结构(使用createBackendPlugin/createBackendModule的src/plugin.ts或src/module.ts,以及用于重新导出的src/index.ts)。using-backstage-backend-services——始终调用。将coreServices.logger和(对于插件)coreServices.httpRouter设为默认依赖;如果需求暗示需要其他服务,则提供这些服务(例如,用于持久化的数据库、用于定期工作的调度器、用于跨插件调用的身份验证等)。- 如果需求涉及目录数据,则以(后端模式)调用
using-backstage-catalog。 - 如果需求描述授权操作(“只有管理员可以……”“必须拥有……权限”“仅所有者可用”),则以(后端模式)调用
using-backstage-permissions。将coreServices.permissions添加到依赖项,并在路由处理程序中添加permissions.authorize检查。
专业后端模板:
catalog-provider-module——完成基础后端技能后,还要调用creating-backstage-catalog-provider。scaffolder-backend-module——完成基础后端技能后,还要调用creating-backstage-scaffolder-action。
库模板(plugin-node-library、plugin-common-library):不自动调用——这些模板与框架无关。
对于关联插件集,运行三条 yarn new 命令后:
-
在
plugins/<id>-common/src/index.ts中填入计划要求的共享 TypeScript 类型。-common中应包含:- 领域接口和类型别名(例如
JiraProject、JiraIssue) - 后端路由返回且前端 Hook 使用的请求/响应结构
- 后端路由和前端共用的常量路径
- 有用的类型谓词/类型守卫
- Zod 模式(如果两端验证相同的结构)
-common中不应包含:- React 或 Express 运行时代码
- 导入
@backstage/frontend-plugin-api或@backstage/backend-plugin-api的任何内容 - 有副作用的初始化器
- 领域接口和类型别名(例如
-
将
@your/plugin-<id>-common(即<id>-common的package.json中的包名)添加到前端和后端的dependencies中。由于这是一个工作区,yarn 会解析到本地包。 -
在前端的数据 Hook(
useJiraProject)中,从@your/plugin-jira-common导入JiraProject。 -
在后端的路由处理程序/服务中,从同一个包导入相同类型,并将其用作路由的响应类型。
-
在仓库根目录运行
yarn install,以配置工作区链接。
然后,按上述流程分别对前端和后端运行各自的包级脚手架后流程。
该模式技能负责提供自己的代码示例;不要直接读取其参考资料。
6. 提议扩展
应用模式后,提议添加用户最初未请求的其他模式:
“插件已创建,并配置了 <X, Y>。还想添加其他内容吗?(权限、自定义 API、路由、测试……)”
如果用户选择添加更多内容,则对这些技能重复步骤 5。
7. 交接
打印最终摘要:
插件已创建于
plugins/<id>。运行yarn dev即可试用。 如果之后需要添加更多模式,请直接调用using-backstage-frontend-system、using-backstage-backend-system、using-backstage-ui、using-backstage-backend-services、using-backstage-catalog、using-backstage-identity、using-backstage-permissions、creating-backstage-catalog-provider、creating-backstage-scaffolder-action、creating-backstage-scaffolder-field、creating-backstage-entity-page-extension,或(高级)creating-backstage-extension-blueprint。
常见问题
- id 必须采用 kebab-case 格式。
yarn new会拒绝Foo或foo_bar。 - 不要以交互方式运行
yarn new——始终传入--select和--option pluginId=。非交互式使用时,这两个标志都是必需的。 - 如果仓库不是 Backstage 仓库(根目录中没有
backstage.json),请在创建脚手架前告知用户。 - 每个模式技能在脚手架创建完成后的模式下,都要求插件刚刚创建;其文件结构可能与较旧的 Backstage 版本不同。模式技能会自行查找文件;不要向它们传递文件路径。