From 63c246ab62deb2af797f45057ccf09bf21776983 Mon Sep 17 00:00:00 2001 From: Vincenzo Scamporlino Date: Wed, 14 Feb 2024 12:04:49 +0100 Subject: [PATCH] docs: migrate plugin as first step Signed-off-by: Vincenzo Scamporlino --- .../building-plugins/migrating.md | 173 ++++++++++-------- 1 file changed, 95 insertions(+), 78 deletions(-) diff --git a/docs/frontend-system/building-plugins/migrating.md b/docs/frontend-system/building-plugins/migrating.md index 504276379b..6f51357c76 100644 --- a/docs/frontend-system/building-plugins/migrating.md +++ b/docs/frontend-system/building-plugins/migrating.md @@ -10,7 +10,72 @@ This guide allows you to migrate a frontend plugin and its own components, route The main concept is that routes, components, apis are now extensions. You can use the appropriate extension creators to migrate all of them to extensions. -## Pages +## Migrating the plugin + +In the legacy frontend system a plugin was defined in its own `plugin.ts` file as following: + +```ts title="my-plugin/src/plugin.ts" + import { createPlugin } from '@backstage/core-plugin-api'; + + export const myPlugin = createPlugin({ + id: 'my-plugin', + apis: [], + routes: { + ... + }, + externalRoutes: { + ... + }, + }); +``` + +In order to migrate the actual definition of the plugin you need to recreate the plugin using the new `createPlugin` utility exported by `@backstage/frontend-plugin-api`. +The new `createPlugin` function doesn't accept apis anymore as apis are now extensions. + +```ts title="my-plugin/src/alpha.ts" + import { createPlugin } from '@backstage/frontend-plugin-api'; + + export default createPlugin({ + id: 'my-plugin', + // bind all the extensions to the plugin + /* highlight-next-line */ + extensions: [], + // convert old route refs to the new system + /* highlight-next-line */ + routes: convertLegacyRouteRefs({ + ... + }), + /* highlight-next-line */ + externalRoutes: convertLegacyRouteRefs({ + ... + }), + }); +``` + +The code above binds all the extensions to the plugin. _Important_: Make sure to export the plugin as default export of your package as a separate entrypoint, preferably `/alpha`, as suggested by the code snippet above. Make sure `src/alpha.ts` is exported in your `package.json`: + +```ts title="my-plugin/package.json" + "exports": { + ".": "./src/index.ts", + /* highlight-add-next-line */ + "./alpha": "./src/alpha.ts", + "./package.json": "./package.json" + }, + "typesVersions": { + "*": { + /* highlight-add-start */ + "alpha": [ + "src/alpha.ts" + ], + /* highlight-add-end */ + "package.json": [ + "package.json" + ] + } + }, +``` + +## Migrating Pages Pages that were previously created using the `createRoutableExtension` extension function can be migrated to the new Frontend System using the `createPageExtension` extension creator, exported by `@backstage/frontend-plugin-api`. @@ -50,11 +115,27 @@ const fooPage = createPageExtension({ }); ``` -## Components +then add the `fooPage` extension to the plugin: + +```ts title="my-plugin/src/alpha.ts" + import { createPlugin } from '@backstage/frontend-plugin-api'; + + export default createPlugin({ + id: 'my-plugin', + // bind all the extensions to the plugin + /* highlight-remove-next-line */ + extensions: [], + /* highlight-add-next-line */ + extensions: [fooPage], + ... + }); +``` + +## Migrating Components The equivalent utility to replace components created with `createComponentExtension` is `createExtension` from `@backstage/frontend-plugin-api`. However, we recommend searching for an appropriate extension first, considering using `createExtension` as the last option for more complex scenarios. -## APIs +## Migrating APIs There are a few things to keep in mind in regards to utility APIs. @@ -84,16 +165,10 @@ export const workApiRef = createApiRef({ Note at the top of the file that it uses the updated import from `@backstage/frontend-plugin-api` that we migrated in the previous section, instead of the old `@backstage/core-plugin-api`. -### Plugin package changes - -Now let's turn to the main plugin package where the plugin itself is exported. You will probably already have a `createPlugin` call in here. Before we changed the `core-plugin-api` imports it'll have looked somewhat similar to the following: +Now let's migrate the implementation of the api. Before we changed the `core-plugin-api` imports the api would have looked somewhat similar to the following: ```tsx title="in @internal/plugin-example, NOTE THIS IS LEGACY CODE" -import { - storageApiRef, - createPlugin, - createApiFactory, -} from '@backstage/core-plugin-api'; +import { storageApiRef, createApiFactory } from '@backstage/core-plugin-api'; import { workApiRef } from '@internal/plugin-example-react'; import { WorkImpl } from './WorkImpl'; @@ -102,27 +177,18 @@ const exampleWorkApi = createApiFactory({ deps: { storageApi: storageApiRef }, factory: ({ storageApi }) => new WorkImpl({ storageApi }), }); - -/** @public */ -export const catalogPlugin = createPlugin({ - id: 'example', - apis: [exampleWorkApi], -}); ``` The major changes we'll make are -- Optionally change the old imports to the new package as per the top section of this guide +- Change the old `@backstage/core-plugin-api` imports to the new `@backstage/frontend-plugin-api` package as per the top section of this guide - Wrap the existing API factory in a `createApiExtension` -- Change to the new version of `createPlugin` which exports this extension -- Change the plugin export to be the default instead The end result, after simplifying imports and cleaning up a bit, might look like this: ```tsx title="in @internal/plugin-example" import { storageApiRef, - createPlugin, createApiFactory, createApiExtension, } from '@backstage/frontend-plugin-api'; @@ -138,31 +204,7 @@ const exampleWorkApi = createApiExtension({ }); ``` -### Further work - -Since utility APIs are now complete extensions, you may want to take a bigger look at how they used to be used, and what the new frontend system offers. You may for example consider [adding configurability or inputs](../utility-apis/02-creating.md) to your API, if that makes sense for your current application. - -## Plugin - -In the legacy frontend system a plugin was defined in its own `plugin.ts` file as following: - -```ts title="my-plugin/src/plugin.ts" - import { createPlugin } from '@backstage/core-plugin-api'; - - export const myPlugin = createPlugin({ - id: 'my-plugin', - apis: [exampleWorkApi], - routes: { - ... - }, - externalRoutes: { - ... - }, - }); -``` - -In order to migrate the actual definition of the plugin you need to recreate the plugin using the new `createPlugin` utility exported by `@backstage/frontend-plugin-api`. -The new `createPlugin` function doesn't accept apis anymore as apis are now extensions. +Finally, let's add the `exampleWorkApi` extension to the plugin: ```ts title="my-plugin/src/alpha.ts" import { createPlugin } from '@backstage/frontend-plugin-api'; @@ -170,39 +212,14 @@ The new `createPlugin` function doesn't accept apis anymore as apis are now exte export default createPlugin({ id: 'my-plugin', // bind all the extensions to the plugin - /* highlight-next-line */ - extensions: [homePage, exampleWorkApi], - // convert old route refs to the new system - /* highlight-next-line */ - routes: convertLegacyRouteRefs({ - ... - }), - /* highlight-next-line */ - externalRoutes: convertLegacyRouteRefs({ - ... - }), + /* highlight-remove-next-line */ + extensions: [fooPage], + /* highlight-add-next-line */ + extensions: [exampleWorkApi, fooPage], + ... }); ``` -The code above binds all the extensions to the plugin. _Important_: Make sure to export the plugin as default export of your package as a separate entrypoint, preferably `/alpha`, as suggested by the code snippet above. Make sure `src/alpha.ts` is exported in your `package.json`: +### Further work -```ts title="my-plugin/package.json" - "exports": { - ".": "./src/index.ts", - /* highlight-add-next-line */ - "./alpha": "./src/alpha.ts", - "./package.json": "./package.json" - }, - "typesVersions": { - "*": { - /* highlight-add-start */ - "alpha": [ - "src/alpha.ts" - ], - /* highlight-add-end */ - "package.json": [ - "package.json" - ] - } - }, -``` +Since utility APIs are now complete extensions, you may want to take a bigger look at how they used to be used, and what the new frontend system offers. You may for example consider [adding configurability or inputs](../utility-apis/02-creating.md) to your API, if that makes sense for your current application.