Skip to content

打包与发布

挂件开发完成后,要让其他用户能装上你的挂件,需要把开发目录打成一个 .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.jsonindex.html 等文件,是一个 gift-roll/ 子目录。

3. 安装流程(用户视角)

  1. 打开主播酱 → 素材面板 →「挂件」分类 →「创意工坊」按钮;
  2. 切换到「我的挂件」Tab,点右上角「安装」;
  3. 选择 .zip 文件;
  4. 主播酱执行下列校验,任一失败即拒绝并提示原因:
    • zip 根目录存在 manifest.json
    • manifest.json 通过 JSON Schema 校验(见 manifest 规范 §6);
    • manifest.sdkVersion ≤ 当前客户端支持上限;
    • manifest.id 不与已安装挂件冲突(同 id 时提示「升级」或「覆盖」);
    • zip 体积 ≤ 50 MB(防止误打包大资源);
  5. 校验通过后解压到 userData/widgets/<id>/(Windows: %APPDATA%\zbj-client\widgets\<id>\);
  6. 挂件出现在「我的挂件」列表,可拖入画布。

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.versionversion 是用户能感知到「有新版可装」的唯一信号——发新版前别忘了改。

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 分钟,看挂件是否稳定、内存有没有持续上涨