ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Backstage 实战入门:从零创建你的第一个开发者门户(Golden Path:Create App)

Backstage 实战入门:从零创建你的第一个开发者门户(Golden Path:Create App) Backstage 实战入门从零创建你的第一个开发者门户Golden PathCreate App【免费下载链接】backstageBackstage is an open framework for building developer portals项目地址: https://gitcode.com/GitHub_Trending/ba/backstage本文是 Backstage 官方 Golden Path 系列四部曲创建应用、编写插件、生产部署、门户推广中的第一部围绕backstage/create-app脚手架、本地开发、登录认证、插件安装、主题定制与版本更新等核心环节带你从空目录起步亲手跑起一个带示例数据、可本地开发的 Backstage 应用。读完本文你将掌握 Backstage 应用的标准工程结构、本地开发工作流以及后续自定义门户所需的核心操作技能。Golden Path 系列与本文定位Backstage 是一个用于构建开发者门户Developer Portal的开源框架。Golden Path 系列共 4 个部分按照完成顺序依次推进Create App本文创建并初始化你的第一个 Backstage 应用Plugins在此基础上编写你自己的插件Deployment将应用部署到生产环境Adoption帮助团队把开发者门户推广落地唯一不要求先完成前序步骤即可阅读的部分。即便你不是技术背景也可以跳过本系列直接阅读 adoption 路径学习如何让团队的开发者门户获得成功。但请务必保证本指南 100% 完成后再进入其他 Golden Path。本路径的各个主题页面位于 docs/golden-path/create-app 目录下包括脚手架001、本地开发002、插件安装003、登录004、主题定制005与版本更新006六个章节。前置准备搭建本地开发环境创建应用之前请先确认你的机器满足以下条件操作系统Unix 系操作系统如 Linux、macOS或 Windows Subsystem for LinuxWSLGNU 构建环境命令行下可用make与build-essentialDebian/Ubuntu等构建工具macOS 上执行xcode-select --install安装 Xcode 命令行工具安装依赖的账号权限需要具有安装依赖所需的提升权限网络工具已安装curl或wgetNode.js使用 Active LTS 版本官方版本策略见 versioning-policy。推荐用nvm管理例如nvm install lts/iron安装 Node 20yarnBackstage 当前使用 Yarn 4.4.1执行corepack enable后运行yarn set version 4.4.1固定版本git需要安装 git 用于版本管理与模板获取。注意本文创建的并非生产就绪安装也不包含组织专属信息。如何针对你的使用场景定制 Backstage正是本指南后续要逐步展开的内容。第一步用 create-app 脚手架生成应用1.1 运行交互式脚手架命令在终端中进入你希望创建新目录的位置然后执行npx backstage/create-applatest该命令是交互式的会询问你要为应用取什么名字这个名字同时也是为你创建的新文件夹名。命令执行过程中你会看到类似下面的输出? Enter a name for the app [required] my-backstage-app Creating the app... Checking if the directory is available: checking my-backstage-app ✔ Creating a temporary app directory: Preparing files: copying .dockerignore ✔ copying .eslintignore ✔ templating .eslintrc.js.hbs ✔ ... Moving to final location: moving my-backstage-app ✔ fetching yarn.lock seed ✔ Installing dependencies: executing yarn install ✔ executing yarn tsc ✔ Successfully created my-backstage-app整个过程会先检查目录可用性、在临时目录准备文件复制静态文件、渲染.hbs模板、移动到最终位置并获取yarn.lock种子文件最后执行yarn install与yarn tsc完成依赖安装和类型检查。完整安装可能需要几分钟加载过程长时间转圈是正常的——后台有大量工作在并行进行。1.2 生成的应用结构脚手架完成后你会得到一个带示例数据、可直接运行的 Backstage 应用。其简化目录结构如下app ├── app-config.yaml ├── catalog-info.yaml ├── package.json └── packages ├── app └── backend各组成部分说明app-config.yaml应用的主配置文件。配置定义与读取的完整说明见 confcatalog-info.yaml软件目录Software Catalog实体的描述符文件。实体描述符格式可参考 software-catalog 下的文档package.json项目根 package.json。注意不要在根 package.json 添加 npm 依赖——它们应安装到对应的 workspace 中而不是根目录packages/Lerna 叶子包leaf packages即workspaces这里的每个目录都是一个独立包由 lerna 统一管理packages/app/一个功能完整的 Backstage 前端应用是了解 Backstage 的良好起点packages/backend/内置后端为认证、软件目录、软件模板、TechDocs 等功能提供支撑。脚手架使用的模板来源即仓库中的 packages/create-app 包你可以在其中查看模板文件.hbs模板等的完整形态。第二步本地开发与运行2.1 启动应用进入应用目录并启动cd my-backstage-app # 换成你的应用名 yarn startyarn start会在同一窗口中以两个独立进程分别命名为[0]和[1]同时运行前端与后端。前端编译完成后浏览器窗口会自动打开小贴士如果浏览器没有自动打开看到[0] webpack compiled successfully消息后直接访问http://localhost:3000即可看到你的 Backstage 应用。启动完成后你会看到门户主页2.2 本地开发架构yarn start实际运行了两个部分前端网站位于packages/app默认监听3000端口。它是一个 React 应用带有对插件友好的强默认配置。本地开发使用rspack做快速编译提供近乎即时的反馈后端位于packages/backend默认监听7007端口。它是一个 Node.js 应用通过express提供 HTTP 服务并连接数据库。本地开发默认使用sqlite作为数据库。它是适合本地开发的内存级快速数据库但由于其临时性不要依赖它在多次yarn start之间保留数据不过热重载hot reload期间数据库状态会被保留。2.3 热重载开发体验前端与后端都支持热重载前端每当保存 React 应用使用的文件后稍等片刻你会看到Rspack compiled successfully后端你会看到Change detected, restarting the development server...随后是服务端的初始化日志。这种保存即生效的开发循环是本地迭代插件与定制功能的核心体验。生产架构数据库选型、多实例部署等则属于 deployment Golden Path 的范畴。2.4 常见问题应用没有运行在 X 端口Backstage 默认使用3000前端与7007后端端口。请确认命令没有报错退出对于远程或容器化环境请确保这两个端口可被访问。第三步登录你的实例3.1 前置条件在开始本步前请先按照 authentication 教程完成 GitHub OAuth 应用设置。3.2 登录流程运行yarn start并访问http://localhost:3000。如果尚未登录你会看到登录界面选择GitHubprovider 并点击Sign in按钮浏览器会跳转到 GitHub 的 OAuth 授权页。请核对页面上列出的 scopes 与你之前在认证教程中配置的一致点击Confirm后即可回到 Backstage 界面并完成登录。如果已经登录则会自动进入实例。3.3 验证登录结果登录后点击左侧导航栏中的Settings项进入个人资料页。如果你能看到来自 GitHub 的头像和用户名说明 GitHub 认证集成已成功配置。若未显示请复查 authentication 教程中的每一步是否完整执行。第四步安装插件插件是 Backstage 生态中最有价值的部分。软件目录Software Catalog、搜索Search、软件模板Software Templates本身就是插件——每个插件都提供一系列聚焦的独立功能。4.1 插件包结构命名规范一个插件通常由多个包组合而成。Backstage 的通用命名标准详见 ADR-011以插件x为例x主前端入口包含插件的前端代码x-backend主后端入口包含后端代码x-backend-module-y插件x的可选后端模块y仅含后端代码x-node供后端插件x的使用者共享的工具库不应用于前端x-react供前端插件x的使用者共享的工具库不应用于后端x-common插件x的共享工具库前后端均可使用。并非所有插件都需要全部这些包建议从x和x-backend两个包起步再逐步扩展。backstage-cli new命令会按上述规范自动生成插件的脚手架。4.2 安装后端插件安装插件包含前端与后端两部分推荐先安装后端插件以免前端出现奇怪的报错。安装后端插件通常只需在packages/backend/src/index.ts中加入backend.import(scope/package);保存文件即会触发热重载新插件立刻可用。对于更复杂的情况插件可能要求额外配置这些配置会或应当记录在该插件的README中。后端模块如为目录提供 GitHub、LDAP、AWS 实体摄入能力的 catalog processor 模块的安装方式与后端插件完全相同同样可能在README中要求额外配置。4.3 安装前端插件前端插件有多个入口应遵循插件自身的文档安装。新的前端系统New Frontend System正在大幅简化这一过程。查找插件时建议先浏览官方插件目录与社区维护的插件仓库再考虑自行编写。第五步定制应用主题Backstage 自带默认主题包含浅色light与深色dark两个变体。主题由backstage/theme包提供该包同时包含定制默认主题、乃至创建全新主题的工具。下文均针对新前端系统新 Backstage 应用的默认配置编写。5.1 创建自定义主题创建新主题最便捷的方式是使用backstage/theme导出的createUnifiedTheme函数覆盖默认主题的调色板与字体等基础参数。例如基于默认浅色主题创建新主题import { createBaseThemeOptions, createUnifiedTheme, palettes, } from backstage/theme; export const myTheme createUnifiedTheme({ ...createBaseThemeOptions({ palette: palettes.light, }), fontFamily: Comic Sans MS, defaultPageTheme: home, });建议在packages/app/src下创建theme文件夹放置主题文件保持工程整洁。也可以从零创建一个完全符合BackstageTheme类型由backstage/theme导出的主题。仓库内置的浅色/深色主题本身就是通过createUnifiedTheme构建的参见 packages/theme/src/unified/themes.ts。5.2 注册并使用主题在新前端系统中主题以扩展extension形式通过backstage/plugin-app-react的ThemeBlueprint安装主题扩展被打包进前端模块并传给createApp。首先安装所需包# 在 Backstage 根目录执行 yarn --cwd packages/app add backstage/frontend-plugin-api backstage/plugin-app-react然后在packages/app/src/App.tsx中创建主题扩展并注册import { createApp } from backstage/frontend-defaults; import { createFrontendModule } from backstage/frontend-plugin-api; import { ThemeBlueprint } from backstage/plugin-app-react; import { UnifiedThemeProvider } from backstage/theme; import LightIcon from material-ui/icons/WbSunny; import { myTheme } from ./theme/myTheme; const myThemeExtension ThemeBlueprint.make({ name: my-theme, params: { theme: { id: my-theme, title: My Custom Theme, variant: light, icon: LightIcon /, Provider: ({ children }) ( UnifiedThemeProvider theme{myTheme} children{children} / ), }, }, }); const app createApp({ features: [ createFrontendModule({ pluginId: app, extensions: [myThemeExtension], }), ], }); export default app.createRoot();自定义主题会与内置的浅色/深色主题并列出现。若希望自定义主题替换默认主题可在app-config.yaml中禁用内置主题app: extensions: - theme:app/light: false - theme:app/dark: false5.3 完整主题示例下面是一个覆盖了调色板、页面主题pageTheme与字体完整配置的自定义主题示例packages/app/src/theme/myTheme.ts配色取自 Tokyo Night 风格import { createBaseThemeOptions, createUnifiedTheme, genPageTheme, palettes, shapes, } from backstage/theme; export const myTheme createUnifiedTheme({ ...createBaseThemeOptions({ palette: { ...palettes.light, primary: { main: #343b58 }, secondary: { main: #565a6e }, error: { main: #8c4351 }, warning: { main: #8f5e15 }, info: { main: #34548a }, success: { main: #485e30 }, background: { default: #d5d6db, paper: #d5d6db }, banner: { info: #34548a, error: #8c4351, text: #343b58, link: #565a6e, }, errorBackground: #8c4351, warningBackground: #8f5e15, infoBackground: #343b58, navigation: { background: #343b58, indicator: #8f5e15, color: #d5d6db, selectedColor: #ffffff, }, }, }), defaultPageTheme: home, fontFamily: Comic Sans MS, /* 控制页面头部颜色 */ pageTheme: { home: genPageTheme({ colors: [#8c4351, #343b58], shape: shapes.wave }), documentation: genPageTheme({ colors: [#8c4351, #343b58], shape: shapes.wave2 }), tool: genPageTheme({ colors: [#8c4351, #343b58], shape: shapes.round }), service: genPageTheme({ colors: [#8c4351, #343b58], shape: shapes.wave }), website: genPageTheme({ colors: [#8c4351, #343b58], shape: shapes.wave }), library: genPageTheme({ colors: [#8c4351, #343b58], shape: shapes.wave }), other: genPageTheme({ colors: [#8c4351, #343b58], shape: shapes.wave }), app: genPageTheme({ colors: [#8c4351, #343b58], shape: shapes.wave }), apis: genPageTheme({ colors: [#8c4351, #343b58], shape: shapes.wave }), }, });其中genPageTheme与shapes用于生成各页面类型的头部渐变与形状defaultPageTheme决定未单独指定时的默认页面主题。5.4 自定义排版Typography创建主题时同样可以定制排版。以下是一个精简主题的排版示例import { createBaseThemeOptions, createUnifiedTheme, palettes, } from backstage/theme; export const myTheme createUnifiedTheme({ ...createBaseThemeOptions({ palette: palettes.light, typography: { htmlFontSize: 16, fontFamily: Arial, sans-serif, h1: { fontSize: 54, fontWeight: 700, marginBottom: 10 }, h2: { fontSize: 40, fontWeight: 700, marginBottom: 8 }, h3: { fontSize: 32, fontWeight: 700, marginBottom: 6 }, h4: { fontWeight: 700, fontSize: 28, marginBottom: 6 }, h5: { fontWeight: 700, fontSize: 24, marginBottom: 4 }, h6: { fontWeight: 700, fontSize: 20, marginBottom: 2 }, }, defaultPageTheme: home, }), });若只想覆盖部分排版设置比如仅h1可基于defaultTypography展开后局部覆写import { createBaseThemeOptions, createUnifiedTheme, defaultTypography, palettes, } from backstage/theme; export const myTheme createUnifiedTheme({ ...createBaseThemeOptions({ palette: palettes.light, typography: { ...defaultTypography, htmlFontSize: 16, fontFamily: Roboto, sans-serif, h1: { fontSize: 72, fontWeight: 700, marginBottom: 10 }, }, defaultPageTheme: home, }), });5.5 自定义字体添加自定义字体时先把字体文件放入前端应用src下的assets/fonts目录再按font-face语法声明字体并通过MuiCssBaseline组件的styleOverrides将字体注册进font-face数组import MyCustomFont from ../assets/fonts/My-Custom-Font.woff2; const myCustomFont { fontFamily: My-Custom-Font, fontStyle: normal, fontDisplay: swap, fontWeight: 300, src: local(My-Custom-Font), url(${MyCustomFont}) format(woff2), , }; export const myTheme createUnifiedTheme({ fontFamily: My-Custom-Font, palette: palettes.light, components: { MuiCssBaseline: { styleOverrides: { font-face: [myCustomFont], }, }, }, });如需使用多种字体可在顶层fontFamily设置正文默认字体再通过typography中各级标题的fontFamily覆盖来控制标题字体。例如正文用My-Custom-Font、标题用My-Awesome-Font只需在typography的h1中指定fontFamily: My-Awesome-Font。5.6 覆盖组件样式主题值会被组件样式引用。例如一个 Backstage 组件的样式可能写成const useStyles makeStylesBackstageTheme( theme ({ header: { padding: theme.spacing(3), boxShadow: 0 0 8px 3px rgba(20, 20, 20, 0.3), backgroundImage: theme.page.backgroundImage, }, }), { name: BackstageHeader }, );其中padding取自theme.spacing、backgroundImage取自theme.page.backgroundImage这些值可以通过自定义主题改变但boxShadow没有引用主题值因此仅靠主题无法修改它或新增诸如margin之类未定义的 CSS 规则。这类情况需要创建样式覆盖overrideimport { createBaseThemeOptions, createUnifiedTheme, palettes, } from backstage/theme; export const myTheme createUnifiedTheme({ ...createBaseThemeOptions({ palette: palettes.light, }), fontFamily: Comic Sans MS, defaultPageTheme: home, components: { BackstageHeader: { styleOverrides: { header: ({ theme }) ({ width: auto, margin: 20px, boxShadow: none, borderBottom: 4px solid ${theme.palette.primary.main}, }), }, }, }, });5.7 自定义 Logo主题之外你还可以替换站点左上角的 Logo。在packages/app/src/components/Root/下有两个组件LogoFull.tsx侧边栏展开时使用的大 LogoLogoIcon.tsx侧边栏收起时使用的小 Logo。直接替换这两个组件中的代码为新的 SVG 定义即可。也可以使用 PNG 等其他格式将图片放入如src/components/Root/logo/my-company-logo.png然后import MyCustomLogoFull from ./logo/my-company-logo.png; const LogoFull () { return img src{MyCustomLogoFull} /; };5.8 自定义与新增图标使用IconBundleBlueprint来自backstage/plugin-app-react可以覆盖内置图标或注册额外图标import { createApp } from backstage/frontend-defaults; import { createFrontendModule } from backstage/frontend-plugin-api; import { IconBundleBlueprint } from backstage/plugin-app-react; import { ExampleIcon } from ./assets/customIcons; const customIconBundle IconBundleBlueprint.make({ name: custom-icons, params: { icons: { github: ExampleIcon, }, }, }); const app createApp({ features: [ createFrontendModule({ pluginId: app, extensions: [customIconBundle], }), ], }); export default app.createRoot();新增图标后即可在实体链接entity links等场景引用。例如注册一个alert图标import AlarmIcon from material-ui/icons/Alarm;并放入IconBundleBlueprint的icons映射然后在catalog-info.yaml中引用apiVersion: backstage.io/v1alpha1 kind: Component metadata: name: artist-lookup description: Artist Lookup links: - url: https://example.com/alert title: Alerts icon: alert也可以在代码中通过useApp()的getSystemIcon获取图标import { useApp } from backstage/core-plugin-api; const app useApp(); const alertIcon app.getSystemIcon(alert);注意如果图标既不是默认图标也不是你添加的图标会回退到 Material UI 的LanguageIcon。5.9 侧边栏与主页定制新前端系统中侧边栏由内置的app/nav扩展管理可通过创建NavContentBlueprint扩展来定制包括子菜单与自定义分组详细指引见 08-migrating。主页Homepage的定制方法则见 homepage。第六步保持 Backstage 始终更新Backstage 更像一个库而非应用或服务backstage/create-app只是给你一个可演进的起点。因此保持与最新版本同步是好习惯。6.1 使用 backstage-cli 升级版本Backstage CLI 提供命令将所有backstage包及其依赖统一升级到最新版本yarn backstage-cli versions:bump一次性升级所有backstage包的原因是维护这些包之间相互的依赖关系。默认该命令会将包升级到每月发布的main发布线想追踪每周发布的next发布线可加--release nextyarn backstage-cli versions:bump --release next如果还使用了其他插件可用--pattern更新除backstage/*之外的依赖yarn backstage-cli versions:bump --pattern {backstage,roadiehq}/*6.2 跟随 create-app 模板变化backstage/create-app从一个模板生成应用的初始结构。仓库中的模板会定期更新但你的app与backend包在create-app时已经定型不会自动获得模板更新。因此模板的任何变更都会连同升级说明一起记录在backstage/create-app包的 changelog 中升级包时建议顺带查看。Backstage 当前版本号记录在仓库根目录的backstage.json中本仓库对应的发布历史可见 releases 目录。6.3 使用 Backstage yarn 插件管理版本Backstage yarn 插件可根据backstage.json中的整体版本为每个包确定合适版本免去在 monorepo 中逐个更新package.json的麻烦——添加新的backstage依赖时也无需再手动推算与当前发布线匹配的版本号。要求yarn 4.1.1 及以上版本安装在 monorepo 根目录执行yarn plugin import https://versions.backstage.io/v1/tags/main/yarn-plugin并把产生的文件系统变更提交到仓库使用插件安装后已发布backstage包的版本可替换为字符串backstage:^yarn 会依据backstage.json中的整体版本解析。backstage.json是插件工作的关键务必把它纳入 CI/CD 流水线与容器构建backstage-cli versions:bump会检测插件是否已安装若已安装会自动把整个 monorepo 的依赖迁移到该插件管理方式。建议在准备进行 Backstage 升级时再安装该插件便于确认一切正常工作。6.4 依赖不一致问题Backstage 是使用 Yarn workspaces 的 monorepoapp、backend以及你添加的自定义插件都是拥有各自package.json的独立包。当某个依赖在不同包中版本一致时会被提升hoist到根目录共享版本不一致时yarn 会在特定包内创建独立的node_modules可能导致同一依赖的多个版本并存。Backstage 的核心包实现上允许包重复如backstage/core-plugin-api、backstage/core-components、backstage/plugin-catalog-react、backstage/backend-plugin-api的重复安装都是可接受的但若想优化包体积与安装速度可用yarn dedupe等工具去重。6.5 代理配置Backstage CLI 在设置NODE_USE_ENV_PROXY1时会遵循标准的HTTP_PROXY、HTTPS_PROXY、NO_PROXY环境变量完整说明见 corporate-proxy。在受限网络环境中yarn 有时也需要代理且其设置与其他模块不同若使用 Backstage yarn 插件还需额外的 yarn 代理配置。若所有环境都需要代理可在yarnrc.yml中添加httpProxy与httpsProxy若仅部分环境需要如开发机需要而 CI 不需要则用环境变量YARN_HTTP_PROXY与YARN_HTTPS_PROXY。如果打算使用 Backstage yarn 插件必须同时配置这些 yarn 代理设置否则无法安装插件和运行versions:bump。示例配置export HTTP_PROXYhttp://proxy.company.com:8080 export HTTPS_PROXYhttp://proxy.company.com:8080 export NO_PROXYlocalhost,internal.company.com export NODE_USE_ENV_PROXY1 export YARN_HTTP_PROXY${HTTP_PROXY} # optional export YARN_HTTPS_PROXY${HTTPS_PROXY} # optional6.6 迁移回滚若因某些问题需要降级 Backstage例如用测试环境验证新版本可参考 manual-knex-rollback 指南了解如何使用 Knex 回滚数据库迁移。常见问题与下一步端口问题确认 3000前端与 7007后端未被占用且命令未报错退出容器或远程环境请开放相应端口。至此你已经拥有一个本地可运行、可登录、可安装插件、可深度定制外观、可保持更新的 Backstage 应用。接下来的两个方向想动手编写自己的插件请进入pluginsGolden Pathdocs/golden-path/plugins建议完成后回来补完本路径剩余部分以了解长期维护 Backstage 应用的知识其余读者可以继续学习deploymentGolden Pathdocs/golden-path/deployment/index.md了解生产架构下的数据库、认证、部署、监控与扩容方案。【免费下载链接】backstageBackstage is an open framework for building developer portals项目地址: https://gitcode.com/GitHub_Trending/ba/backstage创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表