Backstage v1.31.0-next.0 版本深度解析:新后端系统 API 收敛与全量迁移指南
【免费下载链接】backstageBackstage is an open framework for building developer portals项目地址: https://gitcode.com/GitHub_Trending/ba/backstage
本篇文章基于 Backstage 仓库中的 docs/releases/v1.31.0-next.0-changelog.md 编写,深入剖析该预发布版本(
-next.0)中影响最深远的破坏性变更:后端插件/模块/服务统一为BackendFeature、identity 与 tokenManager 服务正式移除、feature loader 新范式落地,以及前端系统 v1 扩展支持的终结。读者将掌握这些变更对现有代码的影响面、每个破坏点的精确修复方案,以及如何借助仓库源码理解这些 API 的底层语义。
一、版本总览:一次以“收敛与清理”为主线的迭代
v1.31.0-next.0 是一个next预发布候选版本,覆盖了后端系统(new backend system)、前端系统(new frontend system)、Scaffolder、Auth、Search、Notifications、TechDocs 等数十个包。从变更内容看,本次迭代的主线非常清晰:
- 后端 API 收敛:
createBackendPlugin、createBackendModule、createServiceFactory的返回值从"返回 feature 的函数"收敛为直接的BackendFeature/ServiceFactory对象; - 遗留服务清理:deprecated 已久的 identity service 与 token manager service 被彻底移除,同时给出可复制的替代实现;
- feature loader 成为官方推荐:
discoveryFeatureLoader、dynamicPluginsFeatureDiscoveryLoader取代旧的featureDiscoveryService/dynamicPluginsServiceFactory; - 前端系统 v1 支持终结:v1 扩展(以对象形式声明 inputs/outputs)被移除,扩展创建一律改用 blueprint;
- 实用能力增强:数据库迁移可跳过、缓存 TTL 支持人类可读时长、Scaffolder 模板列表支持按 owner 过滤等。
升级时官方推荐使用 Upgrade Helper 工具核对每个包的依赖版本与 breaking change,仓库中对应的正式发布记录见 v1.31.0.md。
二、核心破坏性变更:插件/模块/服务统一为BackendFeature
2.1 变更内容
d425fc4是本次发布中波及面最广的一条 BREAKING 变更,影响几乎所有后端包:
createBackendPlugin、createBackendModule、createServiceFactory的返回值现在是直接的BackendFeature和ServiceFactory,而不再是之前已废弃的"返回它们的函数"形式。createServiceFactory也不再接受通过函数参数传入直接 options 的回调形式。这同样影响所有coreServices.*服务引用。
从仓库源码可以清楚看到这一语义变化。createBackendPlugin.ts 中,createBackendPlugin(options)直接返回一个带有$$type: '@backstage/BackendFeature'、version: 'v1'、featureType: 'registrations'与getRegistrations()方法的对象,而不再返回可再次调用的函数。这一改动让 backend instance 中的add(...)语义变得纯粹:它接收的就是 feature 本身,而非 feature 工厂。
2.2 对你的代码意味着什么
受影响最大的是测试代码与packages/backend/src/index.ts中注册插件、模块、服务的位置。典型修复如下:
// 修改前(已废弃的写法):注意末尾的括号 backend.add(createBackendModule({ ... })()); // 修改后:直接去掉多余的括号 backend.add(createBackendModule({ ... }));对于曾经用"函数作为createServiceFactory参数"来传递 options 的写法,该模式已长期弃用且本次彻底不再支持。官方建议的替代路径有两个:
- 探索新的multiton 模式(多实例服务引用)以满足按需配置的需求;
- 将设置迁移到app-config中,通过
coreServices.rootConfig读取。
2.3 类型层面的同步清理
f687050与4d82481移除了若干已弃用类型:
| 已移除类型 | 替代类型 |
|---|---|
BackendPluginConfig | CreateBackendPluginOptions |
BackendModuleConfig | CreateBackendModuleOptions |
ExtensionPointConfig | CreateExtensionPointOptions |
ServiceFactoryOrFunction | (删除,不再需要函数与工厂的联合类型) |
同时,IdentityFactoryOptions类型被移除——identity 服务已无法再通过该选项类型定制。
三、identity 与 tokenManager 服务正式移除及替代方案
3.1 移除范围
19ff127标记的变更删除了 backend-plugin-api 中已弃用的 identity 与 token manager 服务,具体影响:
coreServices.identity与coreServices.tokenManager不复存在;- 各包中相关的类型与工具随之移除;
backend-test-utils中对应的 service mock 一并删除(@backstage/backend-test-utils@0.6.0-next.0);backend-defaults默认 backend 实例不再提供这两个服务的实现(@backstage/backend-defaults@0.5.0-next.0)。
此外,@backstage/backend-defaults移除了对"使用旧 token manager 的插件"的向后兼容回退(359fcd7):不再降级使用旧 token manager,而是直接让不支持新认证系统的插件请求失败。因此部署中的所有插件都应托管在新后端系统的 backend 实例中。
backend-common包则保留了向后兼容:legacyPlugin与makeLegacyPlugin助手现在自带 identity 与 token manager 服务的 shim 实现(8ba77ed),并在包内重新声明了已从 backend-plugin-api 移除、但为兼容仍受支持的 token manager 服务(19ff127的 internal refactor)。auth-backend、signals-backend、permission-node、search 各模块等均已完成内部重构,公共 API 不再要求提供 identity 服务或 token manager(详见各包 Patch 中反复出现的19ff127条目)。
3.2 如果你的插件仍依赖这两个服务
@backstage/backend-defaults的 changelog 给出了两个可直接复制的服务实现方案。
重新实现 identity service:
import { coreServices, createServiceFactory, createServiceRef, } from '@backstage/backend-plugin-api'; import { DefaultIdentityClient, IdentityApi, } from '@backstage/plugin-auth-node'; backend.add( createServiceFactory({ service: createServiceRef<IdentityApi>({ id: 'core.identity' }), deps: { discovery: coreServices.discovery, }, async factory({ discovery }) { return DefaultIdentityClient.create({ discovery }); }, }), );重新实现 token manager service:
import { ServerTokenManager, TokenManager } from '@backstage/backend-common'; import { createBackend } from '@backstage/backend-defaults'; import { coreServices, createServiceFactory, createServiceRef, } from '@backstage/backend-plugin-api'; backend.add( createServiceFactory({ service: createServiceRef<TokenManager>({ id: 'core.tokenManager' }), deps: { config: coreServices.rootConfig, logger: coreServices.rootLogger, }, createRootContext({ config, logger }) { return ServerTokenManager.fromConfig(config, { logger, allowDisabledTokenManager: true, }); }, async factory(_deps, tokenManager) { return tokenManager; }, }), );如果仍依赖旧 identity 服务,官方建议尽早迁移到新的认证系统(auth service migration 路线)。本仓库中plugin-auth-backend、plugin-user-settings-backend等已在本版本内用新的 HTTP auth service 替换了旧 identity 服务的用法(如1b98099:"Replaced usage of the deprecated identity service with the new HTTP auth service for the new backend system")。
四、feature loader 新范式:discoveryFeatureLoader与dynamicPluginsFeatureDiscoveryLoader
4.1discoveryFeatureLoader取代featureDiscoveryService
cd38da8弃用了featureDiscoveryServiceFactory与featureDiscoveryServiceRef,7a72ec8在@backstage/backend-defaults中新增导出discoveryFeatureLoader作为替代。它是一个新后端系统的feature loader,会从当前package.json及其依赖中发现后端 feature。
仓库中的实现位于 packages/backend-defaults/src/discoveryFeatureLoader.ts:它通过createBackendFeatureLoader创建,依赖coreServices.rootConfig与coreServices.rootLogger,内部由PackageDiscoveryService调用getBackendFeatures()返回 feature 列表。
新 backend 实例中的用法:
import { createBackend } from '@backstage/backend-defaults'; import { discoveryFeatureLoader } from '@backstage/backend-defaults'; //... const backend = createBackend(); //... backend.add(discoveryFeatureLoader); //... backend.start();4.2 动态插件侧:dynamicPluginsFeatureDiscoveryLoader
@backstage/backend-dynamic-feature-service@0.4.0-next.0中:
dynamicPluginsServiceFactory不再可被当作函数调用(9080f57,BREAKING);如需提供 options 定制工厂,改用dynamicPluginsSchemasServiceFactoryWithOptions;dynamicPluginsServiceRef、dynamicPluginsServiceFactory、dynamicPluginsServiceFactoryWithOptions均被弃用(cd38da8),推荐改用dynamicPluginsFeatureDiscoveryLoader在 new backend system 中发现动态 feature。
基础用法:
import { createBackend } from '@backstage/backend-defaults'; import { dynamicPluginsFeatureDiscoveryLoader } from '@backstage/backend-dynamic-feature-service'; //... const backend = createBackend(); backend.add(dynamicPluginsFeatureDiscoveryLoader); //... backend.start();带 options 的用法(例如注入自定义 module loader):
import { createBackend } from '@backstage/backend-defaults'; import { dynamicPluginsFeatureDiscoveryLoader } from '@backstage/backend-dynamic-feature-service'; import { myCustomModuleLoader } from './myCustomModuleLoader'; //... const backend = createBackend(); backend.add( dynamicPluginsFeatureDiscoveryLoader({ moduleLoader: myCustomModuleLoader, }), ); //... backend.start();此外e27f889放宽了插件默认导出的类型检查:以函数形式(而非对象形式)定义的BackendFeature现在也被接受,方便动态插件场景下兼容两类导出形态。
五、数据库与缓存增强:skipMigrations与人类可读 TTL
5.1 按需跳过数据库迁移
5a8fcb4为@backstage/backend-defaults增加了跳过数据库迁移的选项:在配置中设置skipMigrations: true,可全局生效或按插件 ID 生效。
仓库中的实现位于 DatabaseManager.ts:读取优先级为plugin.<pluginId>.skipMigrations,回退到全局skipMigrations。对应的单元测试见 DatabaseManager.test.ts,覆盖了全局配置、按插件配置以及全局与插件配置叠加(插件级false覆盖全局true)的场景。
配置示例(app-config):
backend: database: # 全局跳过数据库迁移 skipMigrations: true # 或按插件精细控制 plugin: catalog: skipMigrations: true scaffolder: skipMigrations: false5.2 缓存 TTL 支持人类可读时长
66dbf0a让 cache service 的 TTL 支持人类可读时长格式(human duration format,例如'1h'、'30m'),这对配置可读性是一处明显改善——此前需要按特定数值/单位表达 TTL。
六、前端系统:v1 扩展终结与 blueprint 全面接管
本次前端侧变更集中在@backstage/frontend-plugin-api@0.8.0-next.0、@backstage/frontend-app-api@0.9.0-next.0与新增的@backstage/plugin-app@0.1.0-next.0。
6.1 v1 扩展支持移除(BREAKING)
5446061移除了对v1 扩展的支持:
- 使用
createExtension时,不再允许以对象形式声明 inputs 与 outputs; - 除
createComponentExtension外的所有 extension creator 全部移除,一律改用对应的blueprint(如ApiBlueprint、ThemeBlueprint、IconBundleBlueprint等)。
@backstage/frontend-test-utils@0.2.0-next.0同步移除了对"outputs 以对象而非数组定义"的 v1 扩展的测试支持,并删除了 extension tester 上已弃用的.render()方法(e6e488c)。
6.2 扩展类型参数收敛为单一对象(BREAKING)
fec8b57将ExtensionDefinition与ExtensionBlueprint的类型参数改为单一对象参数,基础类型参数导出为ExtensionDefinitionParameters与ExtensionBlueprintParameters。该变更不影响运行时行为,主要影响类型层面的书写方式,迁移映射如下:
| 旧写法 | 新写法 |
|---|---|
ExtensionDefinition<any> | ExtensionDefinition |
ExtensionDefinition<any, any> | ExtensionDefinition |
ExtensionDefinition<TConfig> | ExtensionDefinition<{ config: TConfig }> |
ExtensionDefinition<TConfig, TConfigInput> | ExtensionDefinition<{ config: TConfig, configInput: TConfigInput }> |
如需推断参数类型,可借助ExtensionDefinitionParameters:
import { ExtensionDefinition, ExtensionDefinitionParameters, } from '@backstage/frontend-plugin-api'; function myUtility<T extends ExtensionDefinitionParameters>( ext: ExtensionDefinition<T>, ): T['config'] { // ... }6.3replaces:重定向缺失的 attachTo 点
98850de为createExtensionInput增加replaces支持:允许扩展把"缺失的attachTo点"重定向到新创建扩展的某个 input 上。仓库实现见 createExtensionInput.ts,其配置类型为Array<{ id: string; input: string }>。
export const AppThemeApi = ApiBlueprint.makeWithOverrides({ name: 'app-theme', inputs: { themes: createExtensionInput([ThemeBlueprint.dataRefs.theme], { // attachTo: { id: 'app', input: 'themes'} 将被重定向到本 input replaces: [{ id: 'app', input: 'themes' }], }), }, factory: () { ... } });这一机制与f3a2b91的架构调整相配合:多个内置 API 的实现从 app 内硬编码改为以 API 扩展形式提供,例如ThemeBlueprint创建的扩展现在挂到api:app-theme的themesinput,而非app扩展。
6.4 新增root扩展与@backstage/plugin-app包
4a66456新增root扩展,取代app扩展作为应用的根;同时为扩展的factory新增apis参数,让扩展可以在不依赖 React context 的情况下访问 utility API;2bb9517引入新的@backstage/plugin-app包,集中承载所有内置扩展,便于统一消费与覆盖(override)。frontend-app-api相应移除了传给createApp/createSpecializedApp的已弃用icons属性(62cce6c),改由IconBundleBlueprint.make创建扩展并纳入应用。
七、插件与应用层变更速览
7.1 Scaffolder
- 模板列表按 owner 过滤(
5143616):@backstage/plugin-scaffolder@1.25.0-next.0在TemplateListPage新增EntityOwnerPicker组件; - 评审页自定义名称(
4512f71):@backstage/plugin-scaffolder-react@1.12.0-next.0新增ui:backstage.review.name选项,用于自定义 scaffolder 评审页上的条目名称,并支持渲染title属性而非 key 名; - secret 字段多处修复(
3ebb64f、9a0672a):修复 secret widget 未显示为必填、嵌套对象中无法必填、无法禁用等问题,并支持minLength/maxLength;评审页对 secret 字段显示固定数量的星号; - 评审页 key 展示修复(
8dd6ef6):ReviewState中 key 以完整 schema 路径展示,用>分隔,避免最终 key 部分重复时只显示一个; - 后端废弃
createRouter(62898bd):plugin-scaffolder-backend的createRouter及相关类型标记为 deprecated,应改用新后端系统初始化。
7.2 Signals 与 Notifications
@backstage/plugin-signals@0.0.10-next.0新增SignalsDisplay扩展,可在应用根中直接挂载(5add8e1):
export default app.createRoot( <> <AlertDisplay transientTimeoutMs={2500} /> <OAuthRequestDialog /> <SignalsDisplay /> <AppRouter> <VisitListener /> <Root>{routes}</Root> </AppRouter> </>, );接入后即可移除通过createApp的plugins选项显式安装 signals 插件的方式;
@backstage/plugin-signals-react@0.0.5-next.0修复useSignal中isSignalsAvailable返回值取反的问题(0389801);- signals-backend 与 notifications-backend 均完成对 identity/tokenManager 移除的内部重构。
7.3 Auth 与目录集成
plugin-auth-backend-module-microsoft-provider与plugin-catalog-backend-module-msgraph(3c2d690):允许没有定义 email 的用户被 msgraph 目录插件摄入,并新增userIdMatchingUserEntityAnnotation签名解析器,支持无 email 用户的登录匹配;plugin-auth-backend-module-aws-alb-provider修复从 payload 而非 header 校验签名者的问题(ecbc47e);plugin-catalog-backend修复 by-query 调用中"按非所有实体都存在的字段排序导致结果不全"的问题(53cce86);plugin-catalog的 Entity presentation API 现在只拉取展示实体标题所需字段(180a45f)。
7.4 Search 与其余后端插件的createRouter弃用潮
本版本多个插件的createRouter及相关类型被标记为 deprecated,标志着旧后端系统的逐步退出:scaffolder-backend、signals-backend、techdocs-backend(5b679ac)、permission-backend(fcb9356)、proxy-backend(d298e6e)、user-settings-backend(164ce3e)、search-backend(5726390)、kubernetes-backend(f55f8bf,KubernetesBuilder)等,均建议迁移到新后端系统。
其中 search 侧(5726390)进一步废弃了 collator 工厂(DefaultCatalogCollatorFactory、ToolDocumentCollatorFactory、DefaultTechDocsCollatorFactory),要求迁移到新后端系统后通过 module 方式安装 collator;同时plugin-search-backend-module-elasticsearch、plugin-search-backend-module-pg内部改用LoggerService与DatabaseService替代遗留的Logger与PluginDatabaseManager类型。
7.5 其他值得关注的修补
@backstage/backend-common新增pg-format依赖(2e9ec14),并允许 cache service 接收人类可读 TTL(66dbf0a);@backstage/cli为默认 GitHub App 权限增加checks: 'read'(1b5c264);@backstage/backend-test-utils新增mockErrorHandler工具,便于在测试中 mock 错误中间件(0363bf1);@backstage/plugin-techdocs-backend为 techdocs 缓存同步引入专用 token(086c32d);techdocs-node停止依赖已弃用的@backstage/backend-common(33ebb28);plugin-techdocs-react修复useShadowRootElements可能导致的无限渲染循环(5ee3d27);@backstage/plugin-app-backend、plugin-app-node修复了与新增@backstage/plugin-app包的依赖元数据问题(d3f79d1);create-app更新 Dockerfile 语法(019d9ad)。
八、升级与迁移清单(Checklist)
综合全文变更,从 v1.30 升级到 v1.31.0-next.0 时建议逐项核对:
- 后端注册代码:检查
packages/backend/src/index.ts与测试中所有createBackendPlugin({...})()、createBackendModule({...})()、createServiceFactory(...)(...)形态,删除多余调用括号;移除createServiceFactory的函数回调参数形式,改用 multiton 或 app-config; - 服务依赖:全局搜索
coreServices.identity与coreServices.tokenManager,按第三节代码自行注册替代服务,或完成到新认证系统的迁移(参考本仓库docs/auth目录与plugin-auth-backend的实现); - 类型替换:
BackendPluginConfig→CreateBackendPluginOptions、BackendModuleConfig→CreateBackendModuleOptions、ExtensionPointConfig→CreateExtensionPointOptions,删除ServiceFactoryOrFunction与IdentityFactoryOptions引用; - feature 发现:将
featureDiscoveryServiceFactory/dynamicPluginsServiceFactory用法替换为discoveryFeatureLoader(backend-defaults)与dynamicPluginsFeatureDiscoveryLoader(backend-dynamic-feature-service); - 前端扩展:将仍以对象形式声明 inputs/outputs 的 v1 扩展迁移到 blueprint(
createComponentExtension除外),按 6.2 节映射更新ExtensionDefinition/ExtensionBlueprint类型参数; - 测试代码:更新
renderInTestApp与 extension tester 的用法(移除.render()),可用mockErrorHandler简化错误中间件 mock; - 配置项:按需启用
backend.database.skipMigrations(全局或按插件),cache TTL 可改用人性化时长格式; - 旧后端系统:若仍通过
createRouter初始化 scaffolder、search、signals、techdocs、permission、proxy、user-settings、kubernetes 等插件,请规划迁移到新后端系统,避免后续版本完全移除时的中断。
注意:
-next.0为预发布版本,以上 API 在正式发布前仍可能调整;生产环境升级请以仓库 docs/releases 目录中的正式版本 changelog(如 v1.31.0.md)为准。
【免费下载链接】backstageBackstage is an open framework for building developer portals项目地址: https://gitcode.com/GitHub_Trending/ba/backstage
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考