关于 using-backstage-frontend-system
面向使用 Backstage New Frontend System 创建或修改插件的开发者,提供插件结构、路由、API 和页面的实现模式,也涵盖新脚手架插件的配置。
主要功能
- 01插件与扩展模式
- 02路由引用指南
- 03API 暴露与数据获取模式
- 04页面和子页面配置
- 05NFS Hook 与 API 引用
- 06常见实现误区
适用场景
- 01定义新的 NFS 插件
- 02添加路由、页面或子页面
- 03暴露或读取插件 API
- 04为脚手架生成的插件应用 NFS 模式
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ vinzscam/ backstage-skills --skill using-backstage-frontend-system安装后在 Claude Code 中输入/using-backstage-frontend-system确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/api-extensions.mdhooks.mdpage-extensions.mdplugin-definition.mdroute-refs.mdsub-pages.md详细介绍
Backstage 新前端系统(NFS)模式
何时使用此技能
- 定义新的前端插件(
src/plugin.tsx) - 声明路由引用(
src/routes.ts) - 从插件中公开 API(
src/apis.ts) - 添加页面、子页面或其他扩展(
src/extensions.tsx) - 使用 NFS hooks(
useApi、useRouteRef)
选择合适的模式
| 构建内容 | 模式 | 参考 |
|---|---|---|
| 插件本身 | createFrontendPlugin({ pluginId, ..., extensions }) | references/plugin-definition.md |
| 路由引用 | @backstage/frontend-plugin-api 中的 createRouteRef、createSubRouteRef、createExternalRouteRef | references/route-refs.md |
| 调用后端端点(默认方式) | 使用 fetchApi.fetch 的数据 hook,并用 useAsync / useAsyncFn 包装——不需要客户端类或扩展 | references/api-extensions.md |
| 在开源插件中公开可扩展 API | ApiBlueprint.make({ params }) | references/api-extensions.md |
| 页面(单一路由) | PageBlueprint.make({ params: { path, routeRef, loader } }) | references/page-extensions.md |
| 带标签页的页面 | PageBlueprint(不带 loader)+ SubPageBlueprints | references/sub-pages.md |
| 在组件中读取 API | 来自 @backstage/frontend-plugin-api 的 useApi(apiRef)、useRouteRef(routeRef) | references/hooks.md |
两种调用模式
- 独立模式:用户正在编辑现有的 NFS 插件。选择一个参考并应用。
- 脚手架生成后(由
creating-backstage-plugin为frontend-plugin/frontend-plugin-module模板调用):在刚生成脚手架的插件中配置规范的 NFS 结构——src/routes.ts、使用createFrontendPlugin的src/plugin.tsx,以及一个示例PageBlueprint扩展。
常见注意事项
- 在 NFS 中,插件系统的导入来自
@backstage/frontend-plugin-api,而不是@backstage/core-plugin-api。钩子(useApi、useRouteRef)、引用(identityApiRef、configApiRef、discoveryApiRef、fetchApiRef、storageApiRef、analyticsApiRef)和原语(createApiRef)都位于新包中。 createRouteRef()不接受id参数——id根据拥有该路由的扩展推导得出。createExternalRouteRef({ defaultTarget: '<pluginId>.<routeName>' })——将defaultTarget设为最常见的绑定目标,这样应用就不需要显式调用bindRoutes。- 如果外部路由未绑定,
useRouteRef(externalRef)可能会返回undefined——务必处理undefined的情况。 PageBlueprint加载器中的页面组件不应包含来自@backstage/core-components的Page、Header或PageWithHeader。框架的PageLayout会自动渲染PluginHeader。使用@backstage/ui中的Container作为页面内容最外层的包装容器。只有在需要副标题或自定义操作时,才使用@backstage/ui中的Header。SubPageBlueprint的路径是相对路径(开头没有/)。子页面组件只渲染内容——不包含Page、Header或HeaderTabs。如果需要内边距,可使用@backstage/ui中的Container包裹子页面内容。createApiRef<T>().with({ id, pluginId })——推荐使用构建器形式,以明确所有权。id仍必须全局唯一。只有所属插件(或针对该插件的模块)才能覆盖此 API。- 对于任何
fetchApi.fetch调用,遇到非 OK 响应时,请使用@backstage/errors中的throw await ResponseError.fromResponse(response)进行处理——它会解析响应正文中的结构化错误信息,并生成其他 Backstage UI 界面(例如<ResponseErrorPanel>)能够理解的类型化错误。切勿仅使用throw new Error(\Failed: ${response.status}`)`。
评论
支持 Markdown