用途
该技能适用于在 Backstage 新前端系统(New Frontend System,NFS)中定义或编写前端插件扩展的场景。具体触发时机包括:定义新的前端插件(src/plugin.tsx)、声明路由引用(src/routes.ts)、从插件暴露 API(src/apis.ts)、添加页面、子页面或其他扩展(src/extensions.tsx),以及使用 NFS 钩子(useApi、useRouteRef)。
主要能力与模式选择
技能提供了一张模式对照表,帮助根据任务选择正确的写法:
- 插件本身:使用 createFrontendPlugin({ pluginId, ..., extensions }),参考 references/plugin-definition.md。
- 路由引用:使用来自 @backstage/frontend-plugin-api 的 createRouteRef、createSubRouteRef、createExternalRouteRef,参考 references/route-refs.md。
- 调用后端端点(默认方式):用一个数据钩子包装 useAsync / useAsyncFn 与 fetchApi.fetch,不使用客户端类,也不使用扩展,参考 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。
使用方式
技能支持两种调用模式:
- 独立模式(Standalone):用户正在编辑一个已有的 NFS 插件,选择一个参考文档并应用。
- 脚手架后模式(Post-scaffold):由 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 loader 内的页面组件不应包含来自 @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 的插件(或针对它的模块)才能覆盖该 API。
- 对于任何 fetchApi.fetch 调用,都要用来自 @backstage/errors 的 throw await ResponseError.fromResponse(response) 处理非 OK 响应——它会解析响应体以获取结构化错误信息,并产生其他 Backstage UI 界面(例如 <ResponseErrorPanel>)能够理解的类型化错误。不要只抛出 new Error(
Failed: ${response.status})。
适用场景与限制
该技能面向 Backstage 前端插件开发者,尤其是使用新前端系统进行插件定义、扩展编写与 API 暴露的场景。资料未提供关于收费、价格、平台支持范围或具体效果的信息。