百积木文档
开发指南平台应用、模块与 Bundle 开发平台应用开发

发布并纳入 Bundle

发布平台应用不可变版本,并由 Bundle 组合安装到工作区。

平台应用定义、不可变版本和 Bundle 版本是不同对象。平台应用先发布自己的不可变版本,再由 Bundle 锁定并组合交付。

平台自动托管,无需自行部署静态站点

开发者提交源码、发布平台应用版本,再通过 Bundle 安装或升级交付。平台负责构建产物的托管部署、生成实际入口和提供同源环境配置。 不需要执行 site createsite deployment create,也不需要手工上传静态文件、配置域名、网关或授权地址。 “自动托管”省去的是单独的站点部署;应用版本发布和 Bundle 安装或升级仍须完成。

发布链路

本文完整流程面向 ENVIRONMENT_HOSTED_APP。普通外链不进入前端构建和平台授权链路。

Platform Application
  -> Platform Application Version
  -> Bundle Manifest
  -> Frozen Bundle Version
  -> Workspace Bundle Install
  -> Platform-managed Hosting + Same-origin Configuration
  -> Bundle Installation Authorization

使用 CLI

先确认本机 CLI 的版本和当前命令:

baijimu --version
baijimu platform-app --help
baijimu platform-app version publish --help
baijimu bundle create --help
baijimu bundle version publish --help

环境托管应用使用项目版本发布

使用 CLI 0.56.0 或更高版本。发布 ENVIRONMENT_HOSTED_APP 时指定项目和版本;CLI 会等待项目构建成功,再冻结平台应用版本。无需查询或传入 artifactId,也无需手动传入 Git commit。 --git-commit-id 仍可用于普通外链等非环境托管配置发布,但不能恢复历史 TRUSTED_EXTERNAL_APP 的启动和平台授权。执行前逐级读取目标子命令的 --help

先创建专属项目。项目类型必须使用稳定键 PLATFORM_APPLICATION,不能依赖某个环境里的数字类型 ID:

baijimu project create \
  --workspace-id <workspaceId> \
  --project-type-key PLATFORM_APPLICATION \
  --name <projectName>

平台应用项目的模板归档和 baijimu.platform-application.json 初始内容属于 PLATFORM_APPLICATION 项目类型目录,不由创建命令指定。

项目初始化后会包含 baijimu.platform-application.json。入口、方法、配置 Schema、Manifest、卡片和工作流声明都在这个文件中维护;字段是原生 JSON 对象或数组,不是再次编码的 JSON 字符串。

环境托管前端使用 ENVIRONMENT_HOSTED_APP,入口为版本内相对根路径,例如 /index.html。项目根目录 package.jsonversion 必须等于发布版本,源文件须先提交到项目主线。首次发布时平台读取主线、校验版本并固定源码,再构建不可变制品。重试同一版本沿用已经固定的源码,主线变化不会换源;修改源码必须使用新版本。

配置环境托管前端

新开发的 React/Vite 平台应用使用以下清单。/index.html 是版本构建产物内的入口,不是外部 URL,也不是 Manager 内置路由:

{
  "schemaVersion": "3.0.0",
  "entry": {
    "urlTemplate": "/index.html",
    "type": "ENVIRONMENT_HOSTED_APP",
    "openMode": "WORKSPACE_TAB"
  },
  "methodDefinitions": [
    {
      "target": {
        "type": "module",
        "bundleId": "workspace-core",
        "moduleId": "2108"
      },
      "methods": [
        "listWorkspaceMembers"
      ]
    }
  ],
  "configSchema": {
    "type": "object"
  },
  "manifest": {},
  "cardDefinitions": [],
  "workflowDefinitions": []
}

不要把通用宿主地址当成内置页面

PLATFORM_ROUTE 只适用于平台管理端源码已经注册并随平台发布的真实内置路由。不得把 /workspace/{workspaceId}/platform-app/{platformAppId} 作为 Bundle 应用的默认入口;该地址是平台应用宿主的通用承载路由,不会自动把项目中的 React 页面注册成内置页面。

入口不能包含外部域名、查询串、hash 或 {installId};平台负责生成实际 accessUrl 并追加安装标识。

前端使用标准 SDK 的 createPlatformApplicationClientFromHostedConfiguration(applicationDefinition.id) 初始化, 从同源 /.well-known/baijimu-platform-application.json 读取当前环境配置。应用归档不能覆盖该文件, 也不能把授权地址、API 域名或发布目录固化进源码。见 Web 接入与运行态调用

构建资源与路由

环境托管产物会部署在版本子目录,Vite 必须生成相对资源地址。在 vite.config.ts 中设置:

export default defineConfig({
  base: "./",
  // 其他 Vite 配置
});

平台应用项目的标准“构建 React 应用”动作默认等价于 pnpm run build -- --base=./。发布平台应用并安装 Bundle 后,通过平台返回的 accessUrl 打开实际版本入口,确认其中引用的 JavaScript、CSS 和公共资源都在同一版本目录返回 200。无需另建站点或手工上传前端文件。

资源路径正确不代表 SPA 路由一定正确。没有服务端 rewrite 的版本化静态站点建议使用 HashRouter

import { HashRouter } from "react-router-dom";

export function App() {
  return <HashRouter>{/* routes */}</HashRouter>;
}

如果必须使用 BrowserRouter,它的 basename 必须来自已验证的 releasePath,并且站点服务要把该目录内的前端路由回退到同一个 index.html;没有该能力时使用 HashRouter。安装后应直接访问实际 accessUrl,确认业务首页已渲染且未进入应用的 NotFound 页面;只检查 index.html 和静态资源返回 200 不足以完成验证。

当前入口与历史类型迁移的完整规则见 入口类型与应用清单

把专属项目与 Bundle 内的平台应用一对一绑定:

baijimu platform-app create \
  --workspace-id <workspaceId> \
  --bundle-id <bundleId> \
  --project-id <projectId> \
  --platform-app-id <platformAppId> \
  --name <name>

提交项目文件后,环境托管应用按项目与版本发布:

baijimu platform-app version publish <platformAppId> \
  --workspace-id <workspaceId> \
  --project-id <projectId> \
  --bundle-id <bundleId> \
  --version <semanticVersion>

CLI 等待构建完成后才冻结应用版本。版本与 package.json 不一致、已有版本指向不同提交或构建失败都会终止发布,不会生成可安装的平台应用版本。普通外链等非环境托管配置在该命令上另加 --git-commit-id <40-character-commit-id>;这不意味着历史可信外部应用仍可启动或取得平台 token。

发布服务校验显式传入的项目 ID 必须属于同一工作区且类型为 PLATFORM_APPLICATION,并要求它与平台应用主记录中的 sourceProjectId 一致,再从项目版本绑定的不可变提交读取配置文件(非环境托管配置使用显式提交)。每个平台应用使用一对一绑定的专属项目;平台应用不能在创建或首次采用来源项目后改绑。CLI 0.15.0 起不再接收 methodDefinitionsJson,也不需要 @file 把 JSON 作为命令参数传输。@file 仍可用于其他明确声明接受“JSON 或 @文件”的命令,但不是平台应用版本内容协议。发布成功只会生成新的不可变版本,不会修改已有版本。

迁移历史外部应用

当前 App Gateway 拒绝 TRUSTED_EXTERNAL_APP 启动和平台授权。即使定义或版本发布成功,也不能据此判断应用可用。 历史 STATIC_SPA 站点没有同源配置入口,并不表示平台缺少环境托管能力。迁移目标是让平台托管新应用版本, 不需要为旧站点补配置入口;旧站点地址也不会自动成为新版本的入口。 迁移必须完成整个交付链:

  1. 将前端源码放入该应用专属的 PLATFORM_APPLICATION 项目;尚未绑定项目的历史应用先按当前 CLI 的 platform-app 帮助完成项目绑定。
  2. 把入口改为 ENVIRONMENT_HOSTED_APP/index.html,移除外部地址与 {installId} 模板;保留业务需要的方法、配置及 Bundle 依赖声明。
  3. 升级标准 SDK,改为同源配置初始化;删除自实现的 PKCE、token 存储和手工部署地址,保证相对资源路径和 SPA 路由可迁移。
  4. 设置新的项目版本并提交主线,执行上述项目版本发布命令;发布时等待平台构建成功,不传 artifactId--git-commit-id
  5. 用新的 Bundle 版本锁定平台应用版本,升级目标安装,并从实际入口验证授权和业务能力。

只发布前端、只改入口类型或只升级 SDK 都不能替代完整迁移。原外部站点若继续独立运营,应使用自己的后台授权; 工作区中不需要平台能力的普通链接可以使用 EXTERNAL_URL

纳入 Bundle 并安装

应用版本冻结后,在 Bundle 项目的本地 Git 工作树选择目录中的应用和精确版本:

baijimu bundle manifest catalog <bundle> platform-application --workspace-id <workspaceId>
baijimu bundle manifest include <bundle> platform-application --workspace-id <workspaceId> \
  --file baijimu.bundle.json --name <exactApplicationName> --version <applicationVersion>

CLI 自动取得 Owner 返回的 platformAppId,写入作者清单的 definition.platformApplications 并在线预检。 重名时使用目录返回的 --object-id。审查并提交 Git 后再发布 Bundle,不能根据应用名称手工构造另一种资源身份。

发布 Bundle 版本后,通过 Bundle 安装或升级操作物化平台应用。不要绕过 Bundle 另造一条安装记录来模拟产品交付。

安装或升级前必须先预览。核对依赖计划与工作区当前安装版本;历史依赖范围可能排除已升级的基础套件,导致计划选择旧版。 遇到这种情况,先验证业务能力与当前依赖的兼容性,再发布修正依赖声明的新 Bundle 版本,不要直接接受非预期降级。

预览还会汇总平台应用调用的、由其他依赖 Bundle 提供的精确 Module 方法;清单非空时,Manager 显示确认窗口,CLI 要求显式传入 --confirm-runtime-method-access。客户端回传的是预览得到的结构化清单,后端会重新解析并 精确比较,不接受布尔值代替授权,也不接受客户端追加 service、方法或通配符。同一 Bundle 内部方法不重复提示,但安装器仍会为所有声明方法维护安装态调用身份。

验证清单

发布后至少确认:

  1. 平台应用版本已经发布且内容不可变。
  2. 版本记录的 sourceProjectIdsourceGitCommitId 与发布提交一致。
  3. Bundle 版本内容引用的是同一个平台应用版本。
  4. 工作区 Bundle 资源台账记录了平台应用安装。
  5. 平台应用安装记录的 installId 保持稳定,版本已经更新。
  6. accessUrl 指向当前环境托管的实际版本入口,已追加真实 installId,且不包含 token。
  7. 版本目录中的 HTML、JavaScript、CSS 和公共资源都返回 200,不存在错误的根路径 /assets/... 引用。
  8. 同源环境配置可读取,应用 origin 和 releasePath 与当前版本一致;打开入口会校验工作区成员和已启用的精确 Bundle 安装,再进入 PKCE 授权链路。
  9. 回跳只携带一次性 code,并能成功兑换 token。
  10. 已声明能力可调用,未声明能力被拒绝。
  11. 分享 Manager 的 /bundle-app/{bundleId}/{platformAppId} 入口时,未安装工作区会提示安装整个 Bundle,安装后返回并打开应用。
  12. 跨 Bundle 方法清单与预览一致并已确认;取消确认或篡改清单时安装被拒绝。

资源发布不等于 Bundle 升级

只发布平台应用新版本不会改变 Bundle,也不会升级已安装产品。必须更新 Bundle Manifest、冻结新 Bundle 版本并升级目标安装。

本页内容