可组合系统
摘要
本页介绍了可组合性系统,该系统有助于将众多插件的内容整合到一个 Backstage 应用程序中。
可组合性系统的核心原则是,插件应具有清晰的边界和连接。 它应隔离插件内部的崩溃,但允许在它们之间进行导航。 它应允许只在需要时加载插件,并使插件能够为其他插件提供扩展点。 可组合性系统也是以应用程序优先的思维方式构建的,它优先考虑应用程序的简洁性和清晰度,而不是插件和核心应用程序接口的简洁性和清晰度。
可组合性系统并不是一个单一的应用程序接口,而是一系列模式、基元和应用程序接口的集合。 其核心概念是扩展还有一种称为组件数据的基元,有助于使应用程序的结构更具声明性。 此外还有RouteRef
可帮助以灵活的方式在页面之间进行路由,这一点在整合不同的开源插件时尤为重要。
概念
本节将简要介绍有助于支持可组合性系统的所有概念。
组件数据
组件数据是一种可组合性原语,是为 React 组件提供新数据维度的一种方式。 数据使用一个键附加到 React 组件,然后可以从使用这些组件创建的任何 JSX 元素中读取,使用相同的键,如下例所示:
const MyComponent = () => <h1>This is my component</h1>;
attachComponentData(MyComponent, 'my.data', 5);
const element = <MyComponent />;
const myData = getComponentData(element, 'my.data');
// myData === 5
组件数据的目的是提供一种嵌入数据的方法,这些数据可以在呈现元素之前进行检查。 元素检查是 React 库中相当常见的一种模式,例如react-router
和material-ui
虽然在这些库中通常只检查元素类型和道具,而我们的组件数据增加了更多的结构化访问,并通过允许同时使用和解释一块数据的多个不同版本来简化演化。
组件数据的用例之一是支持通过应用程序中的元素发现路由和插件。 通过这种方式,我们可以让应用程序中的 React 元素树成为真相的来源,既可以知道使用了哪些插件,也可以知道应用程序中的所有顶级插件路由。 不过,组件数据的使用并不局限于这些用例,因为它还可以用作创建新抽象的基元。
扩展
扩展是插件输出到应用程序中使用的内容。 最典型的是 React 组件,但实际上它们可以是任何类型的 JavaScript 值。 它们是通过以下方式创建的create*Extension
函数,并用plugin.provide()
以创建实际导出的扩展名。
扩展类型很简单:
export type Extension<T> = {
expose(plugin: BackstagePlugin): T;
};
扩展的威力来自于不同角色对其使用的钩挂能力。 创建和插件包装由创建函数的所有者控制,Backstage核心能够钩挂到在插件外公开扩展的过程,最终由应用程序控制扩展的使用。
Backstage 核心 API 目前提供两种不同类型的扩展创建器、createComponentExtension
和createRoutableExtension
组件扩展是没有特殊要求的普通 React 组件,例如实体概述页面的卡片。 组件或多或少会按原样导出,但会封装以提供错误边界、懒加载和插件上下文等功能。
可路由扩展建立在组件扩展之上,可用于任何应在特定路由路径上呈现的组件,如顶层页面或实体页面标签内容。 创建可路由扩展时,需要提供一个RouteRef
作为mountPoint
挂载点将是该组件对外的句柄,其他组件和插件如果希望链接到可路由组件,就会使用该挂载点。
到目前为止,核心库中只有两个扩展创建功能,但未来可能会增加更多。 还有一些插件通过自己的扩展提供了扩展功能的方法,比如createScaffolderFieldExtension
从@backstage/plugin-scaffolder
扩展也不与 React 绑定,既可用于为通用 JavaScript 概念建模,也可能是连接 React 以外的呈现库和 Web 框架的桥梁。
从插件的角度看扩展功能
扩展是穿越插件边界的主要方法之一,也是插件提供具体内容供应用程序使用的方式。 它们取代了现有的组件导出概念,例如Router
或*Card
以显示在实体概述页面上。