Skip to main content

为现有 Monorepo 应用程序添加自定义插件

2020 年 9 月 15 日 - v0.1.1-alpha.21

This document takes you through setting up a new plugin for your existing > monorepo with a GitHub provider already setup. If you don't have either of > those, you can clone > simple-backstage-app > which this document builds on. > > This document does not cover authoring a plugin for sharing with the Backstage > community. That will have to be a later discussion. > > We start with a skeleton plugin install. And after verifying its > functionality, extend the Sidebar to make our life easy. Finally, we add > custom code to display GitHub repository information. > > This document assumes you have Node.js 16 active along with Yarn and Python. > Please note, that at the time of this writing, the current version is > 0.1.1-alpha.21. This guide can still be used with future versions, just, > verify as you go. If you run into issues, you can compare your setup with mine > here > > [simple-backstage-app-plugin](https://github.com/johnson-jesse/simple-backst

骨架插件

  1. Start by using the built-in creator. From the terminal and root of your project run: yarn new --select plugin 2. Enter a plugin ID. I used github-playground 3. When the process finishes, let's start the backend: yarn --cwd packages/backend start 4. If you see errors starting, refer to Auth Configuration for more information on environment variables. 5. And now the frontend, from a new terminal window and the root of your project: yarn start 6. As usual, a browser window should popup loading the App. 7. Now manually navigate to our plugin page from your browser: http://localhost:3000/github-playground 8. You should see successful verbiage for this endpoint, Welcome to github-playground!

捷径

让我们添加一个快捷方式。

打开并用以下内容修改 root: packages > app > src > components > Root.tsx

import GitHubIcon from '@material-ui/icons/GitHub';
...
<SidebarItem icon={GitHubIcon} to="github-playground" text="GitHub Repository" />

很简单!应用程序会自动重新加载您的更改。 现在您应该能在侧边栏看到一个 GitHub 图标。 点击它就能链接到我们的新插件。 现在,API 的乐趣就开始了。

身份

我们的第一项修改将是从身份信息应用程序接口(Identity API)中提取信息。

1.首先打开 root: plugins > github-playground > src > components > ExampleComponent > ExampleComponent.tsx 2.添加两个新导入项

// Add identityApiRef to the list of imported from core
import { identityApiRef, useApi } from '@backstage/core-plugin-api';

将 ExampleComponent 从 inline 调整为 block

from inline:

const ExampleComponent = () => ( ... )

以阻止:_

const ExampleComponent = () => {

return (
...
)
}
  1. 现在,在返回语句之前添加我们的钩子和 const 数据
// our API hook
const identityApi = useApi(identityApiRef);

// data to use
const userId = identityApi.getUserId();
const profile = identityApi.getProfile();
  1. 最后,更新 InfoCard 的 jsx,以使用我们的新数据
<InfoCard title={userId}>
<Typography variant="body1">
{`${profile.displayName} | ${profile.email}`}
</Typography>
</InfoCard>

如果一切都已保存,你应该能在 github-playground 页面上看到你的姓名、ID 和电子邮件。 我们的数据访问是同步的,所以我们只需抓取并发送即可。

https://github.com/backstage/backstage/tree/master/contrib

  1. 以下是整个文件,供参考 ExampleComponent.tsx

擦拭

我们最后要处理的文件是 ExampleFetchComponent。 由于改动较多,我们先将该组件清理干净。

1.首先打开 root: plugins > github-playground > src > components > ExampleFetchComponent > ExampleFetchComponent.tsx 2.将文件中的所有内容替换为以下内容:

import React from 'react';
import useAsync from 'react-use/lib/useAsync';
import Alert from '@material-ui/lab/Alert';
import { Table, TableColumn, Progress } from '@backstage/core-components';
import { githubAuthApiRef, useApi } from '@backstage/core-plugin-api';
import { graphql } from '@octokit/graphql';

export const ExampleFetchComponent = () => {
return <div>Nothing to see yet</div>;
};

3.保存并确保没有错误。 如果您的导入程序碍事,请注释掉未使用的导入程序。

为了方便起见,我们将在此文件中添加很多内容。 请不要在产品代码中这样做!

图表模型

GitHub 有一个用于交互的 GraphQL API。 让我们先添加基本的版本库查询

在 ExampleFetchComponent 外部添加查询 const 语句

const query = `{
viewer {
repositories(first: 100) {
totalCount
nodes {
name
createdAt
description
diskUsage
isFork
}
pageInfo {
endCursor
hasNextPage
}
}
}
}`;

2.以这种结构为指导,我们将把查询分成类型部分 3.在 ExampleFetchComponent 外部添加以下内容

type Node = {
name: string;
createdAt: string;
description: string;
diskUsage: number;
isFork: boolean;
};

type Viewer = {
repositories: {
totalCount: number;
nodes: Node[];
pageInfo: {
endCursor: string;
hasNextPage: boolean;
};
};
};

餐桌模型

使用 Backstage 自带的组件库,让我们定义一个自定义表格。 如果我们有数据要显示,就会用到这个组件。

在 ExampleFetchComponent 外部添加以下内容

type DenseTableProps = {
viewer: Viewer;
};

export const DenseTable = ({ viewer }: DenseTableProps) => {
const columns: TableColumn[] = [
{ title: 'Name', field: 'name' },
{ title: 'Created', field: 'createdAt' },
{ title: 'Description', field: 'description' },
{ title: 'Disk Usage', field: 'diskUsage' },
{ title: 'Fork', field: 'isFork' },
];

return (
<Table
title="List Of User's Repositories"
options={{ search: false, paging: false }}
columns={columns}
data={viewer.repositories.nodes}
/>
);
};

The Fetch

我们准备好刷新获取组件了

  1. 在 ExampleFetchComponent 中添加应用程序钩子
const auth = useApi(githubAuthApiRef);
  1. 我们需要访问令牌才能向 GitHub 发出请求,而请求本身是以异步方式获取的。 3. 在 ExampleFetchComponent 中添加 useAsync 块
const { value, loading, error } = useAsync(async (): Promise<any> => {
const token = await auth.getAccessToken();

const gqlEndpoint = graphql.defaults({
// Uncomment baseUrl if using enterprise
// baseUrl: 'https://github.MY-BIZ.com/api',
headers: {
authorization: `token ${token}`,
},
});
const { viewer } = await gqlEndpoint(query);
return viewer;
}, []);

4.解析后的数据被方便地重组为包含 Viewer 类型的 value 和不言自明的布尔值 loading 以及仅在必要时才会出现的 error 。 因此,让我们使用这些作为 4 个多重返回语句中的前 3 个。 5.在我们的异步代码块下方添加 if return 代码块

if (loading) return <Progress />;
if (error) return <Alert severity="error">{error.message}</Alert>;
if (value && value.repositories) return <DenseTable viewer={value} />;

6.这里的第三行利用我们的自定义表接受我们的 Viewer 类型。 7.最后,我们添加 else return 块来捕捉任何其他情况。

return (
<Table
title="List Of User's Repositories"
options={{ search: false, paging: false }}
columns={[]}
data={[]}
/>
);
  1. 保存后,如果我们没有任何错误,你应该会看到一个包含你的仓库基本信息的表格。 9. 下面是整个文件,供参考 ExampleFetchComponent.tsx 10. 我们完成了!你应该会看到你自己的 GitHub 仓库的信息显示在一个基本表格中。 如果你遇到问题,你可以比较支持本文档的仓库,simple-backstage-app-plugin

何去何从

将 ExampleFetchComponent 分解成更小的逻辑部分,包含在 > 它们自己的文件中。 将组件重命名为 ExampleXxx 以外的名称。 > > 你可能会为自己开发的插件感到非常自豪。 请按照下一个教程 > 深入了解如何发布并将其包含在整个 Backstage > 社区中。