主题
打包与发布
挂件开发完成后,要让其他用户能装上你的挂件,需要把开发目录打成一个 .zip 包,对方在主播酱「创意工坊」里选中即可安装。本章讲:
- 标准目录结构与必备文件;
- 打 zip 的正确方式(最容易翻车的环节);
- 用户安装流程与本地存储位置;
- 版本管理建议;
- 未来的市场分发方式。
1. 目录结构
一个可发布的挂件目录应当长这样:
gift-roll/
├── manifest.json ← 必须,挂件根目录第一层
├── index.html ← 默认入口;manifest 未指定 entry 时取此
├── app.js ← 可选,业务脚本
├── style.css ← 可选,样式
├── thumbnail.png ← 强烈推荐,挂件库列表显示
└── assets/ ← 可选,图片/音频/字体等静态资源
├── icon.png
└── ding.mp3唯一硬性要求:manifest.json 必须在解压后的根目录第一层。其余文件按你喜欢的方式组织即可。
如果用 Vite/Webpack 等构建工具,把构建产物(如 dist/)整理成上述结构再打包,不要把源代码、node_modules、.git 等一起打进去。
2. 打 zip
最常见的错误:在 Windows 资源管理器里右键文件夹 → 「发送到」→「压缩文件夹」,得到的 zip 解压后会多一层 gift-roll/ 目录。主播酱安装时会校验失败(manifest.json not found at root)。
正确做法是进入挂件目录后压缩目录内容,不压缩目录本身:
PowerShell(Windows)
pwsh
Compress-Archive -Path gift-roll\* -DestinationPath gift-roll-1.0.0.zip注意 gift-roll\* 末尾的 \*——压缩的是目录内容,不是目录本身。
bash / zsh(macOS / Linux)
bash
cd gift-roll
zip -r ../gift-roll-1.0.0.zip . -x ".*" "node_modules/*" "src/*"-x 排除模式根据实际项目调整。
验证 zip 结构
打包完用以下命令检查 zip 内文件清单:
pwsh
Expand-Archive gift-roll-1.0.0.zip -DestinationPath check
ls check第一层应该直接看到 manifest.json、index.html 等文件,不是一个 gift-roll/ 子目录。
3. 安装流程(用户视角)
- 打开主播酱 → 素材面板 →「挂件」分类 →「创意工坊」按钮;
- 切换到「我的挂件」Tab,点右上角「安装」;
- 选择
.zip文件; - 主播酱执行下列校验,任一失败即拒绝并提示原因:
- zip 根目录存在
manifest.json; manifest.json通过 JSON Schema 校验(见 manifest 规范 §6);manifest.sdkVersion≤ 当前客户端支持上限;manifest.id不与已安装挂件冲突(同 id 时提示「升级」或「覆盖」);- zip 体积 ≤ 50 MB(防止误打包大资源);
- zip 根目录存在
- 校验通过后解压到
userData/widgets/<id>/(Windows:%APPDATA%\zbj-client\widgets\<id>\); - 挂件出现在「我的挂件」列表,可拖入画布。
4. 本地存储位置
| 路径 | 内容 |
|---|---|
userData/widgets/<id>/ | 挂件文件本身(解压后的目录) |
| 主播酱场景文件 | 画布上挂件元素的 widgetId 引用、用户配置、widgetState(实例 storage) |
挂件被删除时,主播酱只删除画布上的元素,不会删除 userData/widgets/<id>/;用户在「我的挂件」里手动卸载才会删源文件。这样设计允许临时移除挂件后再加回去而不丢配置。
5. 版本管理
manifest.version 建议遵循 SemVer:
| 形如 | 含义 |
|---|---|
1.0.0 | 首发稳定版 |
1.0.1 | 补丁:修 bug,行为不变 |
1.1.0 | 小版本:新增配置项 / 主题字段;老配置仍生效 |
2.0.0 | 大版本:移除/重命名配置项,或行为有破坏性变更 |
主播酱对已安装挂件做「检查更新」时,比对的是 manifest.version。升 version 是用户能感知到「有新版可装」的唯一信号——发新版前别忘了改。
升 manifest.sdkVersion 是另一回事,详见 版本策略 §1。当前阶段所有挂件都用 sdkVersion: 1。
6. 给挂件加缩略图
manifest.thumbnail 字段指向挂件目录下的图片(PNG/JPG/WEBP),用于挂件库列表与详情卡片展示。
- 推荐 正方形,尺寸 ≥ 200×200,≤ 50 KB;
- 路径相对
manifest.json,例如"thumbnail": "thumbnail.png"; - 没指定时显示默认占位图,用户在挂件库里区分多个挂件时体验较差。
6.5 选对元素分类 category
manifest.category 决定挂件在客户端中归属哪一类元素:
| 你做的是 | 推荐 category |
|---|---|
| 全新玩法、没有可对应的内置元素(默认情况) | custom |
| 礼物菜单类(横排展示可送礼物 / 礼物排行) | GiftMenu |
| 加班机(倒计时 + 互动加时) | OvertimeMachine |
| 点赞榜 | LikeRank |
| 心愿单 | WishList |
| 弹幕姬 / 弹幕墙 / 弹幕特效 | ChatRenderer |
| 仅展示文本 / 图片 / 视频的轻量挂件 | 对应 Text / Image / Video,或干脆 custom |
影响:
- 选了某分类后,用户在「素材面板」的对应入口(如「加班机」)就能直接看到你的挂件,和内置元素并列;
- 创意工坊「我的挂件」列表会按分类分组;
- 未来上架市场时,
category直接决定挂件在市场页的频道归属——分类选错的挂件可能被市场审核打回。
默认值是 custom,省略字段即可。挂件运行时始终以 CustomWidget 形式渲染,分类不影响实现,作者不需要因为声明了 category 而改变 manifest / SDK 用法的任何东西。
完整规则与陷阱见 manifest 规范 §2.1。
7. 描述与作者信息
| 字段 | 用途 |
|---|---|
name | 挂件库列表显示的名字 |
author | 详情页作者署名 |
description | 详情页一句话简介,建议 ≤ 60 字 |
homepage | 可选 URL,详情页「访问主页」按钮 |
这些信息会一起进入未来的市场列表页,是用户决定要不要装你挂件的依据,认真写。
8. 用户卸载流程
用户在「我的挂件」选中挂件 → 右键「卸载」:
- 删除
userData/widgets/<id>/整个目录; - 删除该
widgetId在所有场景里的实例(操作前会弹确认「将移除画布上的 N 个实例」); - 删除关联的
widgetState。
卸载不可撤销。若用户重新安装同 id 同 version 的挂件,画布上不会自动恢复之前的实例,需要重新拖。
9. 分发渠道
当前可用:
- 私下分发:直接把
.zip文件发给对方(QQ/微信/邮件/网盘均可),对方按 §3 安装; - 官方预置:随主播酱安装包预置的官方挂件,首启即可使用。
规划中的能力(版本策略 §3):
- 应用内市场:挂件作为产品上架,用户在客户端内一键购买/下载/更新;
- 挂件皮肤:同一挂件可发布多套主题预设作为独立 SKU。
上架细节(提交流程、审核标准、定价规则、分成模式)会在市场能力发布前另行公告。
10. 发布前自检清单
□ manifest.json 在 zip 根目录第一层(不要多一层文件夹)
□ manifest.id 全局唯一,确认未与官方/已知第三方挂件冲突
□ manifest.version 比上一版高(如果是发新版)
□ manifest.sdkVersion 写为 1
□ manifest.category 与挂件实际功能匹配(拿不准就 custom,别乱声明替代内置元素)
□ thumbnail 文件实际存在且尺寸合理
□ 没有把 node_modules / .git / 源代码 / 大量未引用资源打进 zip
□ 删掉了开发期的 console.log 与调试代码(或改用 ZBJ.log)
□ 在主播酱内用「安装」流程试装一次,确认没有校验错误
□ 在 1920×1080 与 1280×720 两种画布尺寸下都试拖、测试自适应
□ 拔掉网络试一下:挂件如果依赖在线资源(字体/图片)会怎样?是否有降级
□ 实际开播 3 分钟,看挂件是否稳定、内存有没有持续上涨