news 2026/9/13 11:27:58

Backstage 1.31.0-next.1 变更深度解析:Backend System 1.0 收尾与前端系统重构迁移指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Backstage 1.31.0-next.1 变更深度解析:Backend System 1.0 收尾与前端系统重构迁移指南

Backstage 1.31.0-next.1 变更深度解析:Backend System 1.0 收尾与前端系统重构迁移指南

【免费下载链接】backstageBackstage is an open framework for building developer portals项目地址: https://gitcode.com/GitHub_Trending/ba/backstage

本篇技术指南基于 Backstage 1.31.0-next.1 的官方发布说明,系统梳理该版本在后端系统(Backend System)1.0 收尾工作前端系统(Frontend System)createApp迁移createFrontendModule取代createExtensionOverrides三大主线上的破坏性变更、关键修复与迁移要点,并结合本仓库源码逐一印证底层实现,帮助你评估升级影响并完成平滑迁移。

该版本为预发布版本(next.1),版本号后缀-next表示尚未发布为正式稳定版,用于验证与先行体验。仓库内对应正式版变更记录可在 docs/releases/v1.31.0-changelog.md 查阅。

版本定位与升级路径

1.31.0-next.1 是 Backstage 1.31 系列的第二个预发布版本。整个变更的核心语境是Backend System 1.0:后端基础包大量移除废弃 API、简化返回值类型;同时前端系统持续推进 "默认应用结构" 的封装迁移。所有破坏性变更都标注为BREAKING,升级时建议逐包核对。

  • 使用 Upgrade Helper 可按目标版本自动计算依赖升级路径(输入目标版本1.31.0-next.1即可)。
  • 本仓库根目录 package.json 与 yarn.lock 记录了当前各包的实际依赖解析版本,可作为升级前后比对的基线。

后端系统 1.0 收尾:backend-common 与 backend-defaults 的破坏性变更

host discovery 不再支持basePath

@backstage/backend-common@0.25.0-next.1@backstage/backend-defaults@0.5.0-next.1同时移除了 host discovery 实现中的basePath选项:

BREAKING: 你不能再向 host discovery 实现提供basePath选项。在新后端系统中,插件路由层本身已不再允许选择该路径。

在新后端系统中,插件的路由挂载路径由系统统一管理,basePath这一"每个插件自定义子路径前缀"的能力在架构上已被移除。若你的自定义代码中仍向HostDiscovery或等价实现传入basePath,需要删除该参数并改用插件自身的router路径约定。

dropDatabase等废弃 API 移除

作为 Backend System 1.0 清理工作的一部分(commit988c145/055b75b),一批废弃 API 被彻底删除,无替代实现

  • @backstage/backend-common中废弃的dropDatabase函数被移除;
  • @backstage/backend-defaults/database子路径导出中,LegacyRootDatabaseService类型被移除;
  • create-app相关模板中引用的@backstage/backend-tasks引用也被清理(见下文 CLI 章节)。

dropDatabase原本用于测试场景中清空数据库,其能力在新后端系统的生命周期管理与测试工具链中已被更规范的方式取代。

DatabaseManager.forPlugin直接返回DatabaseService

这是@backstage/backend-defaults/database子路径最值得注意的简化:

  • DatabaseManager.forPlugin的返回值类型现在是DatabaseService本身,而不是此前间接的管理器对象;
  • forPlugin现在必须传入deps参数(loggerlifecycle服务)。

仓库源码 packages/backend-defaults/src/entrypoints/database/DatabaseManager.ts 中的实现印证了这一点:

forPlugin( pluginId: string, deps: { logger: LoggerService; lifecycle: LifecycleService; }, ): DatabaseService { const client = this.getClientType(pluginId).client; const connector = this.connectors[client]; if (!connector) { throw new Error( `Unsupported database client type '${client}' specified for plugin '${pluginId}'`, ); } const getClient = () => this.getDatabase(pluginId, connector, deps); const skip = this.options?.migrations?.skip ?? this.config.getOptionalBoolean(`plugin.${pluginId}.skipMigrations`) ?? this.config.getOptionalBoolean('skipMigrations') ?? false; return { getClient, migrations: { skip } }; }

从源码结构可以推断,forPlugin返回的DatabaseService包含两个核心成员:

  • getClient:按需懒加载(并缓存)该插件的 Knex 客户端连接,databaseCachepluginId为键;
  • migrations.skip:迁移跳过开关,优先级从插件级plugin.<pluginId>.skipMigrations到全局skipMigrations,均未配置时默认为false

同时,DatabaseManager通过plugin.<pluginId>配置块实现"每个插件独立数据库客户端"的覆盖能力(见 DatabaseManager.ts 的getClientType:插件级client配置优先,否则回退到基础client)。

在真正的新后端系统集成点中,databaseServiceFactory(packages/backend-defaults/src/entrypoints/database/databaseServiceFactory.ts)负责把这一切接入coreServices.database

async createRootContext({ config, rootLifecycle, rootLogger }) { return config.getOptional('backend.database') ? DatabaseManager.fromConfig(config, { rootLifecycle, rootLogger }) : DatabaseManager.fromConfig( new ConfigReader({ backend: { database: { client: 'better-sqlite3', connection: ':memory:' }, }, }), { rootLifecycle, rootLogger }, ); }, async factory({ pluginMetadata, lifecycle, logger }, databaseManager) { return databaseManager.forPlugin(pluginMetadata.getId(), { lifecycle, logger, }); },

注意:当未配置backend.database时,工厂会回退到内存版better-sqlite3connection: ':memory:'),这在本地开发与测试中很有用,但生产环境仍需显式配置数据库。

缓存 API 简化:PluginCacheManager移除

/cache子路径同样走向直接返回服务:

  • PluginCacheManager类型被移除(仍可从@backstage/backend-common导入,但在那里已标记废弃,官方建议完全迁移到新后端系统后离开该包);
  • 相应地,CacheManager.forPlugin立即返回CacheService,不再需要额外的.getClient()调用。

源码 packages/backend-defaults/src/entrypoints/cache/CacheManager.ts 印证了这一点——forPlugin现在直接构造并返回DefaultCacheClient

forPlugin(pluginId: string): CacheService { const clientFactory = (options: CacheServiceOptions) => { const ttl = options.defaultTtl ?? this.defaultTtl; return this.getClientWithTtl( pluginId, ttl !== undefined ? ttlToMilliseconds(ttl) : undefined, ); }; return new DefaultCacheClient(clientFactory({}), clientFactory, {}); }

从 CacheManager.ts 的storeFactories可以看到当前支持的后端缓存存储类型:redisvalkeymemcachememoryinfinispan。未配置backend.cache.store时默认使用memory内存缓存。CacheManager.forPlugin会以pluginId作为 Keyv 命名空间,保证不同插件的缓存键互不冲突。

对应集成点 cacheServiceFactory.ts 同样直接消费该返回值:

async createRootContext({ config, logger }) { return CacheManager.fromConfig(config, { logger }); }, async factory({ plugin }, manager) { return manager.forPlugin(plugin.getId()); },

迁移影响:如果你还在用老写法cacheManager.forPlugin(id).getClient(),升级后需要删掉.getClient();如果你还依赖PluginCacheManager类型,请改为直接使用CacheService类型(来自@backstage/backend-plugin-api)。

配置服务化与其他工程化调整

@backstage/backend-defaults@0.5.0-next.1还包含若干非破坏性但值得注意的调整:

  • discovery 配置下沉到根配置(commit622360e):host discovery 相关配置位置调整到配置根节点;
  • 构造器/工厂改为接受ConfigService而非Config(commitfe6fd8c):与后端系统"一切皆服务"的方向一致;
  • 定时任务纳入 OpenTelemetry 追踪(commit5705424):scheduler 核心服务调度的任务现在会被包装为 OpenTelemetry span,方便观测任务执行链路;
  • config schema 缩进规范化(commitb2a329d)。

此外@backstage/backend-app-api@0.10.0-next.1改进了缺失服务依赖的错误提示:现在错误信息会包含插件 ID 与模块 ID(commitc246372),排障时能更快定位是哪个插件/模块缺少服务声明。

前端系统重构:frontend-defaults诞生与createApp迁移

createSpecializedApp回归"裸应用"

@backstage/frontend-app-api@0.9.0-next.1有一处重要的破坏性变更:

BREAKING:createSpecializedApp现在创建一个不带任何默认应用结构或 API的裸应用。如果需要恢复原行为,可以安装@backstage/plugin-app提供的app插件。

同时,createAppCreateAppFeatureLoader导出被标记为废弃,它们正在迁移到@backstage/frontend-defaults

@backstage/frontend-defaults@0.1.0-next.0初始发布

这是本版本新增的包(初始发布,版本0.1.0-next.0),其定位是:

  • 通过createApp提供默认应用装配,取代原来@backstage/frontend-app-api中的createApp
  • 新增CreateAppOptions类型用于createApp的选项;
  • 新增createPublicSignInApp,用于创建公开入口点的应用(如登录页)。

仓库中该包的源码 packages/frontend-defaults/src/createApp.tsx 展示了新createApp的实现轮廓:它会在应用加载时合并discoverAvailableFeatures(从配置中发现特性)与options.features传入的特性,并将@backstage/plugin-appappPlugin作为基础插件注入prepareSpecializedAppCreateAppOptions支持:

export interface CreateAppOptions { features?: (FrontendFeature | FrontendFeatureLoader)[]; bindRoutes?(context: { bind: CreateAppRouteBinder }): void; advanced?: { configLoader?: () => Promise<{ config: ConfigApi }>; extensionFactoryMiddleware?: | ExtensionFactoryMiddleware | ExtensionFactoryMiddleware[]; loadingElement?: ReactNode; pluginInfoResolver?: FrontendPluginInfoResolver; }; }

迁移建议:如果你仍从@backstage/frontend-app-api导入createApp,升级后应改为从@backstage/frontend-defaults导入。只有当确实需要自行搭建完全定制的应用结构时,才考虑createSpecializedApp+ 手动安装app插件。

createFrontendModule取代createExtensionOverrides

@backstage/frontend-plugin-api@0.8.0-next.1引入createFrontendModule作为createExtensionOverrides的替代(后者被标记废弃),并同时废弃BackstagePluginFrontendFeature类型,改用@backstage/frontend-app-api中的FrontendPluginFrontendFeature

源码 packages/frontend-plugin-api/src/wiring/createFrontendModule.ts 中CreateFrontendModuleOptions定义如下:

export interface CreateFrontendModuleOptions< TPluginId extends string, TExtensions extends readonly ExtensionDefinition[], > { pluginId: TPluginId; extensions?: TExtensions; featureFlags?: FeatureFlagConfig[]; if?: FilterPredicate; }

其核心语义:模块用于为某个已存在的插件添加或覆盖扩展,模块提供的扩展与插件提供的扩展 ID 相同时,模块版本始终优先;若对应插件未安装,该模块会被忽略。createFrontendModule内部会将extensionspluginId作为命名空间解析(resolveExtensionDefinitions(options.extensions ?? [], { namespace: pluginId, featureType: 'Module' }))。

官方给出的迁移示例(原文档完整代码):

// Before createExtensionOverrides({ extensions: [ createExtension({ name: 'my-extension', namespace: 'my-namespace', kind: 'test', ... }) ], }); // After createFrontendModule({ pluginId: 'my-namespace', extensions: [ createExtension({ name: 'my-extension', kind: 'test', ... }) ], });

namespace统一收敛为pluginId

配合上述改动,整个前端系统在统一命名空间概念

  • @backstage/core-compat-api@0.3.0-next.1:API 的namespace参数现在默认取发现的pluginId。如果你此前用 ID 直接覆盖 API,其 ID 可能已变化为包含插件 ID 的形式;
  • @backstage/frontend-plugin-api@0.8.0-next.1createExtensionBlueprintcreateExtensionnamespace选项被废弃,不再必需,默认取pluginId
  • @backstage/frontend-app-api@0.9.0-next.1同步移除了废弃的namespace参数(commit948d431),全面改用pluginId

命名约定上,模块变量建议命名为<pluginId>Module<ModuleName>形式。

平台与工具链更新

@backstage/cli@0.27.1-next.1

  • config.d.ts纳入 tsconfigconfig.d.ts文件被加入tsconfig.json的包含文件列表,使 ESLint 能检测其中的问题或废弃用法(commitd2d2313);
  • 模板不再引用 backend-common:脚手架模板更新,新生成的后端代码不再依赖@backstage/backend-common(commit97422b0),与后端系统 1.0 的"迁移离开旧包"方向一致;
  • esbuild 升级^0.23.0(commitf865103);
  • 修复 CSS/SVG 混用导入问题:此前如果单个模块同时导入.css.svg文件,发布后的前端包会生成无效的 import 结构,此版本修复(commit569c3f0)。

@backstage/create-app@0.5.19-next.1

  • 与 CLI 同步支持config.d.ts纳入 tsconfig;
  • 模板移除对backend-common的引用;
  • 清理@backstage/backend-tasks引用(该包已废弃)。

@backstage/backend-test-utils@0.6.0-next.1

  • 新增缺失的mockServices.rootConfig.mock服务 mock;
  • 修复mockServices.rootHttpRouter.factory定义中重复回调的问题(commit710f621)。

@backstage/catalog-client@1.6.7-next.0:排序下沉到数据库

getEntities的排序逻辑从 catalog client迁移到数据库查询层(commit1882cfe)。官方明确指出:

请注意,最新版@backstage/catalog-client不会再以与之前相同的方式对实体排序,因为排序现在在数据库查询中完成,而非客户端。如果你依赖实体顺序,可能需要更新后端插件或代码。

这是一个行为变更:同样的请求在升级后可能得到不同顺序的结果。@backstage/plugin-catalog-backend@1.25.3-next.1同步应用了该变更。

@backstage/core-components@0.14.11-next.0

SignInPage组件新增titleComponentprop(commit06b8206),允许用任意ReactNode进一步定制标题显示,适合品牌化登录页。

各插件生态修复与适配亮点

除基础包外,本版本对多个官方插件做了适配新后端系统与修复问题的工作,列举与升级相关度较高的几项:

插件变更要点
@backstage/plugin-notifications-backend@0.4.0-next.1创建新通知时校验通知链接(commitf195972);改用注入式 catalog client
@backstage/plugin-notifications-backend-module-email@0.3.0-next.1改用注入式 catalog client(commit5edd344
@backstage/plugin-catalog-backend-module-github@0.7.3-next.1重构为在新后端系统中使用注入的 catalog client(commit5edd344
@backstage/plugin-catalog-graph@0.4.9-next.1修复CatalogGraphPage中点击节点后按返回键导航失效的问题(commitda91078),此前该问题在不同浏览器下表现各异
@backstage/plugin-kubernetes-backend@0.18.6-next.1缺少适当配置时跳过启动(commitca96b66),避免启动即失败
@backstage/plugin-auth-backend-module-aws-alb-provider@0.2.0-next.1claims 中缺少 email 时抛出正确错误(commit8d1fb8d
@backstage/plugin-auth-node@0.5.2-next.1扩展 "unable to resolve user identity" 错误信息(commitc46eb0f),便于定位身份解析失败原因
@backstage/plugin-signals@0.0.10-next.1SignalsDisplay组件扩展命名(commit3e9b1a4
@backstage/plugin-catalog-unprocessed-entities@0.2.8-next.0DevTools 未处理实体表格增加 Location 路径、上次发现时间与下次刷新时间等附加信息(commit4f08c85

此外@backstage/plugin-catalog-backend-module-gitlab@0.4.2-next.1内部改用新的 cache manager(commit53b24d9),@backstage/plugin-scaffolder-react@1.12.0-next.1use-immer升级到^0.10.0@backstage/codemods@0.1.50-next.0升级jscodeshift^0.16.0@backstage/repo-tools@0.9.7-next.1升级@useoptic/openapi-utilities

升级检查清单

综合以上变更,升级到 1.31.0-next.1(及随后的 1.31 正式版)时建议按以下清单核对:

  1. 后端代码

    • 全局搜索dropDatabaseLegacyRootDatabaseServicePluginCacheManager,确认无残留引用;
    • 检查CacheManager.forPlugin(...)调用链,删除多余的.getClient()
    • 检查DatabaseManager.forPlugin(...)调用,补上depsloggerlifecycle),并按新的DatabaseService返回类型调整消费代码;
    • 检查 host discovery 相关代码是否传入了basePath,如有则移除;
    • 检查后端插件构造函数/工厂中直接使用Config的地方,考虑迁移为ConfigService
    • 确认依赖实体排序结果的应用是否受影响(cataloggetEntities排序已移至数据库)。
  2. 前端代码

    • @backstage/frontend-app-apicreateApp导入迁移到@backstage/frontend-defaults
    • createExtensionOverrides迁移为createFrontendModule(提供pluginId);
    • 检查createExtension/createExtensionBlueprint/ API 覆盖中的namespace参数,移除后按pluginId语义调整;
    • 如使用createSpecializedApp,确认是否需要手动安装@backstage/plugin-appapp插件。
  3. 工程配置

    • 运行yarn install更新依赖后,用yarn tscyarn lint检查config.d.ts相关的类型/ESLint 告警;
    • 若使用 CLI 模板新建插件,新生成代码将不再引用backend-commonbackend-tasks

本变更记录对应的完整正式版发布说明见 docs/releases/v1.31.0.md,各包详细 API 演进可对照仓库中packages/*/CHANGELOG.mdreport*.api.md文件交叉验证。

【免费下载链接】backstageBackstage is an open framework for building developer portals项目地址: https://gitcode.com/GitHub_Trending/ba/backstage

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/13 11:22:24

Next.js项目初始化与配置全指南

1. 项目概述 2026年&#xff0c;Next.js已经成为现代Web开发的主流框架之一。这个系列文章将记录我从零开始搭建Next.js项目的完整过程&#xff0c;首篇重点讲解如何正确初始化一个Next.js项目。作为React的元框架&#xff0c;Next.js提供了开箱即用的服务端渲染、静态站点生成…

作者头像 李华
网站建设 2026/9/13 11:20:51

Python应用容器化实战:从Docker到Kubernetes的部署指南

写Python写了好几年&#xff0c;最让我头疼的从来不是语言本身&#xff0c;而是"在我电脑上能跑"这句话。本地开发环境好不容易跑起来的服务&#xff0c;交给别人一部署就崩&#xff0c;要么Python版本对不上&#xff0c;要么系统库缺失&#xff0c;要么MySQL连不上&…

作者头像 李华
网站建设 2026/9/13 11:20:41

Flipper Zero 扫雷游戏全解析:玩法、源码架构与 fbt 编译部署指南

Flipper Zero 扫雷游戏全解析&#xff1a;玩法、源码架构与 fbt 编译部署指南 【免费下载链接】Flipper Playground (and dump) of stuff I make or modify for the Flipper Zero 项目地址: https://gitcode.com/GitHub_Trending/fl/Flipper 本指南以仓库中收录的社区作…

作者头像 李华
网站建设 2026/9/13 11:20:08

Triton深度学习编译器:高效GPU编程新范式

1. Triton项目概述Triton是一个用于编写高效自定义深度学习原语的语言和编译器项目&#xff0c;由triton-lang组织在GitHub上维护。这个开源项目旨在提供比CUDA更高生产力、同时比其他领域特定语言(DSL)更灵活的编程环境。经过十年发展&#xff0c;Triton已经从最初的学术研究项…

作者头像 李华