开发、打包并发布 Custom App
从官方脚手架开始,理解 manifest、PtApp、打包校验与发布后验证,并核对目标环境和版本。
开发前确认目标环境与版本
本文面向已获准接入 Custom Apps 的团队。开始前,与接入负责人确认目标工作区、使用者、数据来源,以及谁负责上传和发布。看得到管理入口,不代表所有运行能力都已在当前环境启用。
带后端的应用需要目标平台支持 App Runtime。本地开发能运行,不证明目标平台已经可以上传或发布。下文按当前官方脚手架说明;已有应用应先记录使用的脚手架标签、SDK 与平台版本,再决定是否升级,不要把不同年代的初始化方式混在一起。
从官方脚手架开始
- 查看官方脚手架的正式标签和 README,与接入负责人确认采用哪个版本。不要直接把持续变化的默认分支当作上线基准。
- 安装依赖,在项目根目录运行
npm run dev。 - 实现目标画面,同时检查没有权限、没有数据与请求失败时的表现。
- 依次运行
npm run doctor、npm run build、npm run package,得到用于上传的 ZIP。
doctor 报告的约定问题应先修复再重新构建。构建成功只说明产物能够生成,不等于普通成员已经能正确使用。
理解 manifest 与版本的区别
manifest.json 必须位于 ZIP 根目录,entry 指向包内实际存在的 HTML 相对路径。不要在压缩包外层多套一层项目目录,优先使用脚手架的 package 命令生成产物。
| 项目 | 检查内容 |
|---|---|
| 脚手架标签 | 开发起点的版本,与应用发布版本分开。 |
| version | 应用版本;交付修改时更新,便于辨认,并与 package.json 保持一致。平台版本记录以发布结果为准。 |
| schemaVersion | 平台契约版本:纯前端为 1,带 backend 声明的结构为 2。 |
| entry / icon | 声明文件真实存在于 ZIP,路径与大小写一致。 |
| scopes | 声明应用需要的能力;声明本身不等于授权,也不扩大使用者的数据权限。 |
使用后端时,按所用版本声明处理入口、资源和出站目标等内容。完整字段参考官方 manifest 示例,不要把不需要的能力一并留下。
等待 PtApp 上下文就绪
应用在与平台画面隔离的 iframe 中运行,通过 window.PtApp 使用上下文、提示、确认框和导航等能力。不要设计成直接操作父页面 DOM,或依赖平台内部的非公开全局变量。
对象存在不代表上下文已经准备好:桥接握手结束前,context 可能为空。依赖 sid 或语言的逻辑,应使用脚手架的读取方式并响应 on('context', ...) 更新,避免在首帧把空值永久缓存。也应保留开发入口中的 await installDevHost()。
应用内部使用 hash 路由,需要把位置同步给宿主时使用 nav.syncRoute。完成后直接刷新详情页,确认能恢复原位置。具体契约请查看官方开发约定。
分别检查数据能力与授权
在匹配的 SDK 与平台环境中,前端可使用 PtApp.data.query() 查询分析数据。读取 context 本身并不会得到分析数据;请查看所用 SDK 随包提供的 node_modules/@ptengine/app-sdk/data-query.llms.txt,选择 queryType、时间范围与字段,不要猜测参数。位置也见官方脚手架说明。
业务资产和外部系统同样需要分别检查能力开通与使用者权限。用普通成员实际运行,并确认权限之外的数据不会返回。结果为空时先检查目标档案、期间、真实存在的事件与属性,不要把空结果解释为业务表现为零。
后端调用应沿用脚手架提供的 API 包装与认证逻辑,不自行省略验证,也不把秘密信息放进前端。需要的 scope 和首次授权还可参考应用访问与数据权限指南。
区分本地预览与平台内验证
本地应通过 npm run dev 启动。对于带后端的结构,只单独启动 vite 可能缺少认证所需处理,出现页面能打开但 API 一直失败的情况。
如果目标环境提供“本地开发地址”,在管理页为目标应用设置 dev server 地址,再从平台内打开。检查真实档案切换、语言、权限和路由恢复。此时看到的内容可能不同于已发布版本,验证结束后应退出开发模式。
同事与你看到的内容不一致时,先对照本地开发设置和当前生效版本,再用另一个浏览器或普通成员检查公开版本。个人开发画面能够运行,不应被报告为已经交付给团队。
上传前检查应用包
- 整理不使用的依赖和素材,确认公开产物中没有秘密信息。
- 检查前端
base: './'、manifest 所在位置,以及入口文件是否一致。 - 通过 doctor 与 build 后,使用 package 生成 ZIP。
- 解压检查结构,确认引用的 CSS、图片、字体等资源完整。
- 容量与允许文件格式以所用版本规则及上传界面为准,不把旧文档的数字跨版本当成固定上限。
即使生成的 ZIP 名称相同,也应记录其对应源码、应用版本与检查日期。package 成功只意味着打包结束,不代表已经发布。
首次创建应用记录
- 选择目标档案,打开“探索应用 → 自定义应用管理”。若看不到“新建”,请接入负责人确认创建权限与当前环境的限定开放范围。
- 点击“新建”,填写使用者能够辨认的应用名称。
- 已有准备好的 ZIP 时可一并选择;应用包为可选项,也可以先只填写名称创建记录,稍后再上传。
- 点击“创建应用”并确认结果;若附带 ZIP,继续按下方 schema 分支处理。
- 若应用已创建但上传失败,回到列表找到已生成的记录,在该应用中重试上传,避免重复新建。
创建记录本身不等于已经具备可运行的公开版本。向成员交付前,还需确认生效版本、发布状态和共享权限。
上传到目标应用并确认发布结果
不要把上传当成没有影响的预检查。当前 schema 1 上传链路会在完成时切换生效版本;schema 2 则通过包含后端的专用部署画面处理。更新已有应用时,应先确定影响范围与验证负责人。
- 在“自定义应用管理”进入目标应用详情,核对档案、应用名、当前版本和发布状态。
- 点击“上传版本”,选择已完成 doctor、build 和 package 的 ZIP;若创建时已附带 ZIP,直接继续当前显示的处理流程。
- schema 1:确认上传完成及生效版本,不能假设还需另按发布按钮才会影响使用者。
- schema 2:在“部署新版本”查看要求的配置和密钥检查结果。缺少项目时,通过“去填配置”“去填密钥”保存所需值,再回到部署画面重新检查;秘密信息不能放入普通配置栏。
- 检查通过后点击“部署”,确认处理结果,再核对应用详情中的版本列表和发布状态。部署与应用发布状态不同;若仍为草稿或暂停,确认内容后使用界面的“发布”或“恢复”操作。
- 让普通成员从“探索应用”打开,验证数据读取与主要操作,再按需要固定到导航。
处理中断、结果不明时,重试前先查当前版本。文件已传输、部署完成、应用已发布、导航已固定需要分别确认。CLI 的 --publish 同样伴随发布,不应用作纯检查;CI 接入参考官方脚手架与目标环境流程。
按错误定位上传问题
| 错误 | 优先检查 |
|---|---|
| ZIP_INVALID | ZIP 本身是否能打开;用官方 package 命令重新打包。 |
| MANIFEST_MISSING / MANIFEST_INVALID | 是否位于根目录;JSON 与 schema 是否有效。 |
| ENTRY_NOT_FOUND | entry 指向的文件是否存在,路径和大小写是否一致。 |
| EXT_FORBIDDEN / ICON_INVALID | 所用版本是否允许这种格式;移除无关文件。 |
| ICON_NOT_FOUND | icon 引用的资源是否真实包含在包内。 |
| PATH_TRAVERSAL | 包内引用是否越出目录;修复结构后重新打包。 |
| TOO_LARGE / TOO_MANY_FILES | 体积和文件数是否超限;检查素材和无关产物。 |
实际错误名称可能随环境而变化。不要通过关闭校验解决问题,应修正对应字段。仍无法处理时,提供应用版本、错误文本和复现步骤。
排查白屏、样式与权限问题
白屏时先看控制台与资源 404,核对相对 base 和 entry。只有结构没有样式时,检查 Tailwind 是否能扫描到组件库实际安装位置的构建产物;只有弹窗样式异常时,检查主题类是否挂在 html,而不是仅挂在 #root。
PtApp 为空时检查启动方式和初始化等待。API 的 401/403 应分别核对认证、授权与 scope;也可能是目标环境尚未具备 Runtime 条件,不能仅靠反复重试解决。结合官方排错文档与 doctor 的提示定位,不要先改掉打包和鉴权约定。
发布后约定更新与交接
交接不应只有 ZIP。应记录源码、依赖锁定信息、脚手架版本、manifest、当前生效版、配置项名称与负责人、验证结果。秘密信息本身保留在受管理的配置位置,不写进交接文档或聊天。
更新后重新检查普通成员的界面、目标档案、数据读取与主要操作。暂停应用、删除应用、撤销外部系统授权是不同动作;开始正式运营前,应与接入负责人确认当前环境真正支持的恢复方式与影响范围。