服务商代开发小程序:ext.json 配置、directCommit 与批量发版流程
面向已经做过小程序、现在要给多个商户批量发版的场景,把服务商代开发的流程、ext.json 字段、commit 接口参数和返回码梳理一遍,方便对照实现。
一、服务商代开发小程序
官方文档:
提交代码审核前的前置检查项
除了名称、简介、类目和头像,还需要检查用户隐私保护指引是否已经配置好(查看「配置小程序用户隐私保护指引」;公告《关于补充小程序、插件用户隐私保护指引说明》)。如果小程序涉及申请地理位置等相关隐私接口,还需要对相关 API 进行权限申请、在代码中声明(公告:小程序地理位置相关接口调整、地理位置接口新增与相关流程调整)。上传代码以及提交代码审核接口的注意事项,见对应接口文档。
代开发步骤
第三方平台帮助旗下已授权的小程序进行代码管理时,需先开发完成小程序模板,再将模板部署到旗下小程序账号中。
第一步:绑定开发小程序
- 第三方平台的开发人员先到微信公众平台申请一个普通小程序,并完善头像、昵称、简介、服务类目等信息。
- 进入微信开放平台,在第三方平台详情中,将该小程序添加为开发小程序。
绑定为开发小程序后,该小程序在开发者工具中上传的代码会直接上传到开放平台,不会上传到公众平台。
第二步:小程序模板的开发和上传
使用开发小程序的开发者微信号登录微信开发者工具,按正常流程开发和调试,完成后在开发者工具中点击上传。
第三步:添加到小程序模板库,获得模板 ID
从开发者工具上传的代码会先存在草稿箱中,每个开发小程序只保留最新一份上传记录。可以把草稿箱中的代码添加到小程序模板库,模板库中的模板不会被覆盖。最多可以有 200 个代码模板,添加后可以获得模板 ID(TemplateID)。
第四步:调用接口,为旗下授权的小程序部署代码
具体接口详见「上传代码」。注意:小程序授权托管之后,只能使用第三方平台在微信开放平台登记的服务器域名和业务域名。因此,在帮助旗下小程序发布代码之前,需先把服务器域名和业务域名设置到小程序中,设置接口详见「设置服务器域名」和「设置业务域名」。
代开发模式的提交方式
上述流程是「草稿箱 → 模板库 → 小程序」。要直接把代码提交到小程序,可以用 directCommit 直接提交至待审核列表。directCommit 是 ext.json 里的一个参数。
除了通过开发者工具提交代码,还可以通过 miniprogram-ci 提交,directCommit 同样适用于 CI 工具。使用第三方代开发模式,重点需要关注 ext.json 文件。
为什么用第三方平台代开发
- 效率更高:一个小程序模板可以批量提交给大量商家小程序;版本需要更新时也可以批量更新。
- 更可靠:商家小程序将开发权限授权给服务商之后,商家登录公众平台也无法进行版本管理、域名配置等操作,一定程度上避免因商家误操作导致业务故障或不稳定。
- 更快速:平台方在逐步推进更多场景可按照小程序模板进行审核,模板审核通过、且商家小程序满足相关条件时,可加速通过审核。
二、ext.json
官方文档:
小程序运营者可以一键授权给第三方平台,通过第三方平台完成业务。第三方平台在小程序的前后端开发上与直接开发小程序有所区别。
名词:
- open3rd:第三方平台账号,是认证的第三方开发者 Appid(查看路径:微信开放平台 - 管理中心 - 第三方平台 - 详情)
- 3rdMiniProgramAppid:第三方平台申请的并绑定在该平台上的小程序,用于开发小程序模板
- extAppid:授权给第三方平台的小程序
extAppid 的开发调试
ext.json 是一个配置文件,放置在 project.config.json 中 miniprogramRoot 指定的目录中、与 app.json 同级。示例:
{
"extEnable": true,
"extAppid": "wxf9c4501a76931b33",
"directCommit": false,
"ext": { "name": "wechat", "attr": { "host": "open.weixin.qq.com", "users": ["user_1", "user_2"] } },
"extPages": { "pages/logs/logs": { "navigationBarTitleText": "logs" } },
"window": {
"backgroundTextStyle": "light",
"navigationBarBackgroundColor": "#fff",
"navigationBarTitleText": "Demo",
"navigationBarTextStyle": "black"
},
"tabBar": {
"list": [
{ "pagePath": "pages/index/index", "text": "首页" },
{ "pagePath": "pages/logs/logs", "text": "日志" }
]
},
"networkTimeout": { "request": 10000, "downloadFile": 10000 },
"plugins": { "myPlugin": { "version": "1.0.0", "provider": "wxidxxxxxxxxxxxxxxxx" } }
}
注意:第三方代开发小程序,如果已经在 app.json 配置了,那么通过 commit 接口提交代码时,ext_json 里面也需要配置,例如 { "lazyCodeLoading": "requiredComponents" }。
ext.json 中的配置字段分为两种:特有字段、同 app.json 相同的字段。
特有字段
| 属性 | 类型 | 必填 | 描述 |
|---|---|---|---|
| extEnable | Boolean | 是 | 配置 ext.json 是否生效 |
| extAppid | String | 是 | 配置 extAppid |
| ext | Object | 否 | 开发自定义的数据字段 |
| extPages | String Array | 否 | 单独设置每个页面的 json |
| directCommit | Boolean | 否 | 是否直接提交到待审核列表 |
extEnable:规定当前 ext.json 文件是否生效,可通过修改该字段开启和关闭 extAppid 的结合开发。extAppid:授权调试的 AppID,例如填wxf9c4501a76931b33,在 extEnable 为真的情况下,后续开发逻辑都会基于该 AppID 运行。directCommit:规定当前上传操作是否直接上传到 extAppid 的审核列表。为 true 时,开发者在工具中的上传操作会直接上传到对应 extAppid 的审核列表,第三方平台只需要调用https://api.weixin.qq.com/wxa/submit_audit?access_token=TOKEN即可提交审核。为 false 或未定义时,上传操作会直接上传到对应草稿箱。
同 app.json 相同的字段:当 ext.json 中的字段同 app.json 中一致时,ext.json 的字段会覆盖 app.json 中的对应字段。
三、上传小程序代码并生成体验版
官方文档:
流程:第三方平台需要先将草稿添加到代码模板库(addToTemplate),或者从代码模板库中选取某个代码模板,得到对应的模板 id(template_id);然后调用本接口为已授权的小程序上传代码并生成体验版。
请求参数:
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| access_token | String | 是 | 第三方平台接口调用令牌 authorizer_access_token |
| template_id | String | 是 | 代码库中的代码模板 ID,可通过获取代码模板列表接口获取。注意,如果该模板 id 为标准模板库的模板 id,则 ext_json 可支持的参数为:{"extAppid":" ", "ext": {}, "window": {}} |
| ext_json | String | 是 | 用于控制 ext.json 配置文件的内容 |
| user_version | String | 是 | 代码版本号,开发者可自定义(长度不要超过 64 个字符) |
| user_desc | String | 是 | 代码描述,开发者可自定义 |
使用同一模板服务不同小程序的机制:第三方可以将自定义信息放置在 ext_json 中,在模板小程序中,可以使用 wx.getExtConfigSync 接口获取自定义信息,从而区分不同的小程序。ext_json 中有限支持 pages(不可新增页面)、subPackages(不可新增分包页面)、plugins(覆盖模板 app.json 的 plugins 配置)。
配置合并规则:
- ext 整体替换
- pages 整体替换
- extPages 中找到对应页面,同级覆盖 page.json
- window 同级覆盖
- extAppid 直接加到 app.json
- networkTimeout 同级覆盖
- customOpen 整体替换
- tabbar 同级覆盖
- functionPages 整体替换
- subPackages 整体替换
- navigateToMiniProgaramAppIdList 整体替换
- plugins 整体替换
同级覆盖:以 window 同级覆盖为例,遍历 extjson 的 window 对象成员,如果 app.json 的 window 对象存在该成员则覆盖,不存在就添加。
整体替换:以 plugins 整体替换为例,如果 app.json 存在 plugin 对象,就用 extjson 里的 plugin 对象覆盖;不存在就添加。
请求示例:
{
"template_id": "0",
"ext_json": "{\"extAppid\":\"\",\"ext\":{\"attr1\":\"value1\",\"attr2\":\"value2\"},\"extPages\":{\"index\":{},\"search/index\":{}},\"pages\":[\"index\",\"search/index\"],\"window\":{},\"networkTimeout\":{},\"tabBar\":{},\"plugin\":{}}",
"user_version": "V1.0",
"user_desc": "test"
}
常见返回码:
-1系统繁忙85013无效的自定义配置85014无效的模板编号85043模板错误85044代码包超过大小限制85045ext_json 有不存在的路径85046tabBar 中缺少 path85047pages 字段为空85048ext_json 解析失败80082没有权限使用该插件80067找不到使用的插件80066非法的插件版本9402202请勿频繁提交,待上一次操作完成后再提交9402203标准模板 ext_json 错误,传了不合法的参数;如果使用的是标准模板库的模板,ext_json 支持的参数仅为{"extAppid":'', "ext": {}, "window": {}}
相关工具
- miniprogram-ci:微信官方小程序 CI 工具,可在不打开开发者工具的情况下上传/预览代码,
directCommit同样适用于 CI。 - ruochuan12/mini-ci:基于 miniprogram-ci 的工具,支持多选、批量上传与预览。