发布并纳入 Bundle
发布平台应用不可变版本,并由 Bundle 组合安装到工作区。
平台应用定义、不可变版本和 Bundle 版本是不同对象。平台应用先发布自己的不可变版本,再由 Bundle 锁定并组合交付。
平台自动托管,无需自行部署静态站点
开发者提交源码、发布平台应用版本,再通过 Bundle 安装或升级交付。平台负责构建产物的托管部署、生成实际入口和提供同源环境配置。
不需要执行 site create、site 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.json 的 version 必须等于发布版本,源文件须先提交到项目主线。首次发布时平台读取主线、校验版本并固定源码,再构建不可变制品。重试同一版本沿用已经固定的源码,主线变化不会换源;修改源码必须使用新版本。
配置环境托管前端
新开发的 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 站点没有同源配置入口,并不表示平台缺少环境托管能力。迁移目标是让平台托管新应用版本,
不需要为旧站点补配置入口;旧站点地址也不会自动成为新版本的入口。
迁移必须完成整个交付链:
- 将前端源码放入该应用专属的
PLATFORM_APPLICATION项目;尚未绑定项目的历史应用先按当前 CLI 的platform-app帮助完成项目绑定。 - 把入口改为
ENVIRONMENT_HOSTED_APP和/index.html,移除外部地址与{installId}模板;保留业务需要的方法、配置及 Bundle 依赖声明。 - 升级标准 SDK,改为同源配置初始化;删除自实现的 PKCE、token 存储和手工部署地址,保证相对资源路径和 SPA 路由可迁移。
- 设置新的项目版本并提交主线,执行上述项目版本发布命令;发布时等待平台构建成功,不传
artifactId或--git-commit-id。 - 用新的 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
内部方法不重复提示,但安装器仍会为所有声明方法维护安装态调用身份。
验证清单
发布后至少确认:
- 平台应用版本已经发布且内容不可变。
- 版本记录的
sourceProjectId和sourceGitCommitId与发布提交一致。 - Bundle 版本内容引用的是同一个平台应用版本。
- 工作区 Bundle 资源台账记录了平台应用安装。
- 平台应用安装记录的
installId保持稳定,版本已经更新。 accessUrl指向当前环境托管的实际版本入口,已追加真实installId,且不包含 token。- 版本目录中的 HTML、JavaScript、CSS 和公共资源都返回
200,不存在错误的根路径/assets/...引用。 - 同源环境配置可读取,应用 origin 和
releasePath与当前版本一致;打开入口会校验工作区成员和已启用的精确 Bundle 安装,再进入 PKCE 授权链路。 - 回跳只携带一次性
code,并能成功兑换 token。 - 已声明能力可调用,未声明能力被拒绝。
- 分享 Manager 的
/bundle-app/{bundleId}/{platformAppId}入口时,未安装工作区会提示安装整个 Bundle,安装后返回并打开应用。 - 跨 Bundle 方法清单与预览一致并已确认;取消确认或篡改清单时安装被拒绝。
资源发布不等于 Bundle 升级
只发布平台应用新版本不会改变 Bundle,也不会升级已安装产品。必须更新 Bundle Manifest、冻结新 Bundle 版本并升级目标安装。