Backstage v1.23.0-next.1 版本解析:Catalog 位置查询 API、前端新路由体系与 Scaffolder 模板能力增强
【免费下载链接】backstageBackstage is an open framework for building developer portals项目地址: https://gitcode.com/GitHub_Trending/ba/backstage
本文基于当前仓库 docs/releases/v1.23.0-next.1-changelog.md 展开,面向需要升级 Backstage 应用、适配破坏性变更,或希望理解新前端插件系统(Frontend Plugin System)与 Scaffolder 模板引擎细节的开发者。读完本文,你将掌握 v1.23.0-next.1 中
getLocationByEntity新 API 的用法、RouteResolutionsApi替代路由上下文的迁移要点、fetch:template新增的 nunjucks 配置项,以及全部破坏性变更的应对方案,并可结合仓库源码进一步验证实现细节。
一、版本背景与变更总览
v1.23.0-next.1是 Backstage 1.23.0 的第二个预发布版本(next.1),共涉及 100 余个@backstage/*包的版本更新。从变更内容看,本版本存在三条清晰的主线:
- 新前端插件系统(Frontend Plugin System)加速收敛:
frontend-plugin-api、frontend-app-api、core-compat-api等多个包围绕 analytics API、RouteResolutionsApi和默认插件 ID 进行了较大调整,其中包含破坏性变更; - Software Catalog 能力补强:新增「按实体查询 Location」的服务端与客户端 API,并对
queryEntities、GitHub 组织同步做了性能与稳定性优化; - Scaffolder 模板引擎体验升级:
fetch:template/fetch:plain/fetch:file支持上游集成鉴权 token 覆盖,并为 nunjucks 新增trimBlocks、lstripBlocks配置项。
下文将按「破坏性变更优先」的原则逐项展开,并给出可在本仓库中直接验证的源码路径。
二、破坏性变更(Breaking Changes)与迁移指南
1.core-components:移除SidebarIntro与IntroCard
core-components@0.14.0-next.0 中删除了SidebarIntro组件,因为它提供的引导内容对应的功能并不存在;随之一同移除的还有IntroCard。如果你在应用中依赖这两个组件,需要自行迁移到自定义实现,或直接移除相关侧边栏引导文案。
从当前仓库的 packages/core-components/src/layout/Sidebar 目录结构看,Intro相关文件已不在其中,说明该删除在next.1中已生效。迁移时可参考原实现思路:用应用自己的SidebarItem组合实现侧边栏入口,而不是依赖框架内置的引导卡片。
2.frontend-plugin-api:默认插件扩展 ID 从root改为app
frontend-plugin-api@0.6.0-next.1将默认插件扩展(default plugin extension)与插件自身的默认 ID 从root改为app。这意味着在新前端系统下,创建插件时默认生成的扩展 ID 前缀发生了变化:
- 旧:
plugin.<id>/root/... - 新:
plugin.<id>/app/...
如果你在新系统中显式依赖了旧 ID 字符串(例如通过ExtensionBoundary或自定义扩展注册),需要同步更新。同时,该版本还调整了 App 组件扩展的包装方式:1e61ad3移除了对 App 组件扩展的ExtensionBoundary包装,使其能够继承外层上下文,这会影响依赖边界隔离的扩展行为。
3.frontend-app-api:移除实验性createExtensionTreeAPI
frontend-app-api@0.6.0-next.1直接删除了实验性的createExtensionTreeAPI(变更bdf4a8e)。如果你的代码或自定义包中还使用该 API 构建扩展树,必须迁移到新前端系统提供的扩展注册与装配机制。
4.plugin-azure-sites-backend:catalogApi与permissionsApi变为必传参数
plugin-azure-sites-backend@0.2.0-next.1是一个需要重点关注的破坏性变更:createRouter函数现在必须传入catalogApi和permissionsApi,否则 TypeScript 会直接报错。变更日志给出了完整的迁移 diff:
import { createRouter, AzureSitesApi, } from '@backstage/plugin-azure-sites-backend'; import { Router } from 'express'; import { PluginEnvironment } from '../types'; export default async function createPlugin( env: PluginEnvironment, ): Promise<Router> { + const catalogClient = new CatalogClient({ + discoveryApi: env.discovery, + }); return await createRouter({ logger: env.logger, azureSitesApi: AzureSitesApi.fromConfig(env.config), + catalogApi: catalogClient, + permissionsApi: env.permissions, }); }该变更的动机在于:Azure Sites 的start和stop操作现在纳入了 Permissions 框架保护(见下文),后端需要访问 Catalog 与 Permission 服务才能完成鉴权判断。
三、Scaffolder:模板引擎与动作能力增强
1.fetch:template支持 nunjucks 的trimBlocks与lstripBlocks
plugin-scaffolder-backend@1.21.0-next.1为fetch:template动作新增了两个模板引擎配置项(变更e0e5afe),用于控制 nunjucks 对空白字符的处理:
trimBlocks:若设置为true,块(block,而非变量标签)之后的第一个换行符会被移除;lstripBlocks:若设置为true,行首到块开始之间的前导空格与制表符会被剥离。
这两个参数非常适合解决模板渲染后出现多余空行、缩进错乱的问题。在仓库源码 plugins/scaffolder-backend/src/scaffolder/actions/builtin/fetch/template.ts 中可以看到它们被定义为可选布尔值,并经由 templateActionHandler.ts 透传给 nunjucks 渲染器;fetch:template对应的templateFile动作(templateFile.ts)同样支持这两个选项。
一个典型的模板配置示例:
steps: - id: fetch-template name: Fetch Template action: fetch:template input: url: https://github.com/example/template values: name: my-service trimBlocks: true lstripBlocks: true2.fetch:template/fetch:plain/fetch:file支持 token 覆盖
变更78c100b允许在fetch:template、fetch:plain和fetch:file三个动作中提供可选的token参数,用于与上游集成(如 GitHub、GitLab)交互时的鉴权覆盖。该能力同时落地在scaffolder-backend与scaffolder-node两个包中。
以fetch:template为例,token被定义为可选字符串(见 template.ts),在动作处理器中会被透传给fetchContents用于下载模板内容:
- action: fetch:template input: url: https://github.com/my-org/private-template token: ${secrets.TEMPLATE_TOKEN} values: componentId: my-component3. 面向 Node 20+ 的启动校验与脚手架改进
scaffolder-backend新增了两项与运行环境相关的防护:
--no-node-snapshot启动校验:当运行环境为 Node 20+ 时,如果启动时未传入--no-node-snapshot选项,scaffolder-backend会在启动阶段直接抛出错误(变更e1c479d),提示开发者以正确方式启动,避免模板渲染时因 node snapshot 导致异常;- 错误提示下移:
NODE_OPTIONS相关的提示信息被移到SecureTemplater中(变更f6792c6),以便在运行时给出更准确的报错信息。
对应的启动方式示例:
NODE_OPTIONS=--no-node-snapshot yarn start-backend另外,plugin-scaffolder@1.18.0-next.1对EntityPicker做了性能优化:默认情况下只选择实体的kind、metadata.name和metadata.namespace字段(变更9b9c05c),以降低在大数据集上的渲染开销;plugin-scaffolder-react还修复了ui:schema在存在dependencies时被空对象覆盖的问题(82affc7),并为 ActionsPage、ListTaskPage、TemplateEditorPage 统一加入了ScaffolderPageContextMenu便于页面间跳转。
四、Software Catalog:新增「按实体查询 Location」API
1. 服务端实现
plugin-catalog-backend@1.17.0-next.1新增了按实体引用查询 Location 的接口。其核心实现在 plugins/catalog-backend/src/service/DefaultLocationService.ts 与 AuthorizedLocationService.ts 中,路由注册见 createRouter.ts,OpenAPI 定义同步更新在 openapi.yaml。
该接口的价值在于:过去要找到「某个实体是从哪个 Location(如 catalog-info.yaml 的 URL)注册进来的」,需要遍历全部 Location 并逐一比对实体引用,代价较高;现在可以直接按实体引用反查其来源 Location。
2. 客户端 API
catalog-client@1.6.0-next.1对应的新增方法是getLocationByEntity(变更43dad25),实现在 packages/catalog-client/src/CatalogClient.ts:
async getLocationByEntity( entityRef: CompoundEntityRef | string, options?: CatalogRequestOptions, ): Promise<Location | undefined> { return await this.requestOptional( await this.apiClient.getLocationByEntity( { path: parseEntityRef(entityRef) }, options, ), ); }可以看到,它接收CompoundEntityRef或字符串形式的实体引用,内部通过parseEntityRef解析后请求/locations/by-entity/{kind}/{namespace}/{name}这类路径(路径参数定义在 openapi 生成的客户端 中),并复用requestOptional语义——当实体没有关联 Location 时返回undefined而非抛错。对应的客户端测试位于 CatalogClient.test.ts,测试工具实现位于 InMemoryCatalogClient.ts。
典型用法:
import { CatalogClient } from '@backstage/catalog-client'; const catalogClient = new CatalogClient({ discoveryApi }); const location = await catalogClient.getLocationByEntity({ kind: 'Component', namespace: 'default', name: 'my-service', }); console.log(location?.target); // 例如 https://github.com/org/repo/blob/main/catalog-info.yaml3. Catalog 后端其它稳定性修复
queryEntities在limit为 0 时做了性能优化(89b674c);- 回滚了 wildcard discovery 相关改动(
efa8160),修复了AzureUrlReader在通配符路径下无法工作的问题; plugin-catalog-backend-module-github@0.5.0-next.1防止实体提供者在同步失败时错误地从数据库中删除 Users 与 Groups(a950ed0),并减少了针对大型组织的 GraphQL 查询中 Teams/Members 的拉取数量,以规避超时(9477133)。
五、新前端系统:Analytics API 与路由解析重构
1. 新 Analytics API 全面接入
变更e586f79是本次版本在frontend-plugin-api、core-compat-api以及plugin-analytics-module-ga、plugin-analytics-module-ga4、plugin-analytics-module-newrelic-browser三个分析模块中的共同主线,核心动作是让新前端系统全面支持新的 analytics API:
core-compat-api为新前端系统的插件提供了 analytics 兼容层;frontend-app-api将根元素包裹在 analytics context 中,保证所有扩展在任何时候都能拿到 analytics 上下文(变更e586f79在 frontend-app-api 中的部分);- 三个分析模块(GA、GA4、New Relic Browser)均升级到支持新 analytics API 的版本(
plugin-analytics-module-newrelic-browser借此发布了0.1.0首个正式版本)。
如果你在新前端系统中接入埋点,应改为使用新的 analytics API 而非旧版useAnalytics实现。core-plugin-api还顺带改进:当某个 API 实现找不到时,抛出更具体的NotImplementedError而非泛化错误(e586f79)。
2.RouteResolutionsApi取代路由上下文
frontend-plugin-api@0.6.0-next.1新增RouteResolutionsApi(bc621aa),作为旧路由上下文(routing context)的替代品;frontend-app-api、core-compat-api、frontend-test-utils等包同步迁移到新 API。在源码中,该 API 的定义位于 packages/frontend-plugin-api/src/apis/definitions/RouteResolutionApi.ts,其apiRef为routeResolutionApiRef(见该文件第 68 行),useRouteRef等路由 Hook 已改为通过它解析路由目标(见 useRouteRef.tsx)。
配套地,变更46b63de允许新系统中的外部路由引用(external route refs)声明defaultTarget——当采用方未显式绑定路由时,会默认解析到该目标。这降低了插件之间路由对接的配置成本。
3. 组件 key 改为使用ComponentRefID
frontend-app-api@0.6.0-next.1修复了一个潜在 bug(fb9b5e7):默认ComponentsApi实现此前用组件引用实例(reference instance)作为组件 key,当@backstage/frontend-plugin-api被重复安装(存在多份实例)时会导致应用异常;现在改为使用ComponentRef的 ID 作为 key,彻底规避该问题。
六、集成层:限流检测与鉴权 token 支持
1. GitHub 限流检测修复
@backstage/integration@1.9.0-next.0修复了 GitHub 集成中的限流检测逻辑(e27b7f3):
- HTTP 429:现在直接识别为限流;
- HTTP 403:此前检测的响应头有误,现在改为检查
x-ratelimit-remaining头。
对应实现见 packages/integration/src/github/GithubIntegration.ts,其判定条件是response.status === 429或x-ratelimit-remaining === '0';配套测试在 GithubIntegration.test.ts。该修复能显著提升 GitHub API 限流场景下的退避重试准确性,backend-common也同步升级以共享该能力。
2.readTree/readUrl/search支持 token
backend-common@0.21.0-next.1与backend-plugin-api@0.6.10-next.1均支持在readTree、readUrl、search中传入token(变更1f020fe),使后端在读取外部仓库内容时可以显式提供鉴权 token,与 Scaffolder 的 token 覆盖能力形成呼应。
七、认证与其它值得关注的变化
1. AWS ALB Auth Provider 迁移为独立模块
plugin-auth-backend-module-aws-alb-provider@0.1.0-next.0发布,AWS ALB 认证提供方从plugin-auth-backend内迁移到独立的模块包(变更23a98f8)。plugin-auth-backend@0.20.4-next.1同步改为依赖该新模块。升级后如需在旧后端系统中使用 AWS ALB 登录,应按新模块的方式引入:
// 新后端系统 backend.add(import('@backstage/plugin-auth-backend-module-aws-alb-provider'));2. Azure Sites 操作纳入 Permissions 框架
plugin-azure-sites、plugin-azure-sites-backend、plugin-azure-sites-common三个包共同完成了 Azure Sitesstart/stop操作的权限保护(变更5a409bb)。变更日志给出了一个典型的策略示例——只允许 Catalog 实体的 owner 触发针对该实体站点的操作:
// packages/backend/src/plugins/permission.ts import { azureSitesActionPermission } from '@backstage/plugin-azure-sites-common'; ... class TestPermissionPolicy implements PermissionPolicy { async handle( request: PolicyQuery, user?: BackstageIdentityResponse, ): Promise<PolicyDecision> { if (isPermission(request.permission, azureSitesActionPermission)) { return createCatalogConditionalDecision( request.permission, catalogConditions.isEntityOwner({ claims: user?.identity.ownershipEntityRefs ?? [], }), ); } ... return { result: AuthorizeResult.ALLOW, }; } ... }3. 其它小幅修复与升级
app-defaults/core-app-api/test-utils:Bitbucket 认证的defaultScopes从无效的team修正为account(7da67ce),修复 Bitbucket 登录问题;plugin-azure-devops-backend:修复extractPartsFromAsset导致合法路径(如.assets/image.png)中前导.被错误移除的问题(25bda45);plugin-kubernetes-node:引入PinnipedHelper类,支持通过 Pinniped 对 Kubernetes 集群进行认证(cceed8a);cli@0.25.2-next.1:升级 jest,并修复实验性模块发现(module discovery)下生成非法__backstage-autodetected-plugins__.js的问题;repo-tools:修复生成模板中注释重复的问题,并移除生成代码中 OpenAPI spec 的标题与版本头部(c04c42b);plugin-catalog-graph:改用CatalogClient.getEntitiesByRefs()批量获取实体,减少后端请求次数(f937aae);plugin-home:为HomePageVisitedByType增加过滤器支持(384c132)。
八、升级建议与自检清单
针对 v1.23.0-next.1,升级时建议按以下顺序自查:
- 搜索
SidebarIntro/IntroCard引用,确认已移除或替换; - 检查新前端系统扩展 ID:将依赖
root默认 ID 的代码迁移为app; - 确认
createExtensionTree已无引用; - 为 Azure Sites 后端补齐
catalogApi与permissionsApi,并按需编写权限策略; - Node 20+ 环境:以
--no-node-snapshot启动 scaffolder-backend,或在NODE_OPTIONS中声明; - 模板渲染异常排查:如需更严格的空白控制,为
fetch:template增加trimBlocks/lstripBlocks; - 私有模板/上游仓库:需要鉴权时,为
fetch:*动作传入token覆盖。
如果希望深入验证上述行为,可继续阅读:
- Catalog 新 API:CatalogClient.ts、DefaultLocationService.ts 及对应测试 CatalogClient.test.ts;
- 新路由体系:RouteResolutionApi.ts、useRouteRef.tsx;
- 模板引擎配置:template.ts、templateActionHandler.ts;
- 限流检测:GithubIntegration.ts。
【免费下载链接】backstageBackstage is an open framework for building developer portals项目地址: https://gitcode.com/GitHub_Trending/ba/backstage
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考