1. 背景
做过跨平台小程序的朋友们都应该知道,每一次需求迭代都会经历从 开发 -> 测试 -> 验收 -> 上线 这个完整链路的过程,但是每一次都需要开发提供二维码给到测试、设计、产品,再或者是需要修改某些参数后再提供一个新的二维码,再或是这个重复的编译到不同小程序平台再做几十个appid的代码上传操作。这些且鸡肋浪费时间的操作会让我重新思考能不能做一个平台出来给他们去使用,从而解放我们开发人的双手。
假如你有如下几个痛点,那么我希望这篇文章能够给你一点启发和思路,来为你们的团队提效
- 同时维护多个不同平台小程序
- 每次发布需要多个appid主体
- 生成预览二维码或上传代码至小程序后台前需要修改某些参数
- 总之就是一些很浪费时间的操作......
2. 需求概述
2.1 需求整理
本设计主要满足以下需求:
- 产出一个miniprogram-ci工具npm包供开发者使用
- 产出一个web平台供测试、产品、设计使用预览、上传小程序
- 代码上传日志
2.2 功能整理
本需求涉及以下功能范围:
- 生成小程序二维码
- 上传小程序代码至微信、支付宝后台
- 支持批量修改、替换文件操作
- 错误日志记录
- 飞书消息推送
- Hbuilder Cli编译不同平台小程序(uniapp)
至于为什么要用Hbuilder Cli、这是一个历史遗留问题了。一般来说可考虑脚本编译(taro、uniapp 等cli创建的项目)
3. 方案设计
整体roadmap

miniprogram-ci (npm包)
脚本执行逻辑
ci全流程设计
4. 落地实施
- miniprogram-ci 提供了预览、上传微信支付宝小程序相关功能、配合我们一些落地业务的能力集成了一个npm包提供给我们小程序业务方进行接入,根目录需要配置一个
mp-ci.config.js
文件来配合我们npm包的脚本使用
js
module.exports = {
// 支付宝ci必填
alipay: {
// 登录授权数据
authentication: {
// 工具 ID
toolId: "xxxxxxxxxx",
// 私钥
privateKey:
"xxxxxxxxx",
},
projectPath: "unpackage/dist/dev/mp-alipay", // 用于生成单次预览二维码的路径
uploadPath: "unpackage/dist/build/mp-alipay", // 用于上传代码包至小程序后台的路径
pagesListPath: "unpackage/dist/build/mp-alipay/app.json", // 拉取小程序所有page的配置
// 用于生成单次预览二维码的配置
formGenerate: function () {
return {
appid: 'xxxxxx', // 预览的appid
replace_list: [
{
filePath: 'unpackage/dist/build/mp-alipay/pages/index/index.json', // 文件路径
type: 'json', // 文件格式
editValue: {
defaultTitle: '测试一下title变化' // 需要修改的参数
}
}
],
}
},
// 用于上传代码包到小程序后台的配置
dynamicConfig: {
replace: function () {
return [
{
appid: "xxxx",
version: "x.x.x",
replace_list: [],
},
{
appid: "xxxxx",
version: "x.x.x",
replace_list: [],
},
{
appid: "xxxxx",
version: "x.x.x",
replace_list: [],
}
];
},
},
},
// 微信ci必填
// 配置同上
wechat: {
projectPath: "unpackage/dist/dev/mp-weixin",
uploadPath: "unpackage/dist/build/mp-weixin",
pagesListPath: "unpackage/dist/dev/mp-weixin/app.json",
dynamicConfig: {
replace: function () {
return [
{
appid: "wxxxxxxxx",
privateKey:"-----BEGIN RSA PRIVATExxxxxx",
version: "x.x.x",
replace_list: [
{
filePath: 'unpackage/dist/build/mp-weixin/project.config.json',
type: 'json',
editValue: {
appid: "xxxxxx"
}
}
],
},
{
appid: "wxd4xxxxxxf",
privateKey:"-----BEGIN RSxxxxxxx\n",
version: "x.x.x",
replace_list: [
{
filePath: 'unpackage/dist/build/mp-weixin/project.config.json',
type: 'json',
editValue: {
appid: "xxxxxx"
}
}
],
},
];
},
},
formGenerate: function () {
return {
appid: 'wxbab3xxxxxx',
privateKey:"xxxxxxn",
replace_list: [
{
filePath: 'unpackage/dist/dev/mp-weixin/pages/shop/shop.json',
type: 'json',
editValue: {
navigationBarTitleText: '测试替换title',
},
},
],
}
},
},
};
- 关于小程序授权信息的配置可以根据你们的实际情况设置在你们的
ci环境变量
里 - 本方案中既提供了
previewKeyPath
的传入方式或根据配置的数据生成的授权信息 - 本npm包出了提供
preview
、upload
功能外也暴露出了相关api供业务方二次封装使用
关于技术选型方面本例子中的npm包采用了rollup
打包的方式产出commonjs
和esmodule
的产物
- 小程序构建平台 提供了web可视化界面供测试、产品等人员使用,集成了上述所有功能并在完善其交互使用户有更好的体验(目前已投入生产)

- 该平台原理是通过我们业务小程序的
分支
或git tag
在代码提交阶段触发相应ci进行打包编译处理,处理后的产物我们考虑放在oss上存储
,使用时即可直接获取,无需重复经历打包编译阶段。
关于技术选型方面本平台采用了
auto-miniprogram-frontend
Arco Design Pro 主要是对字节有特殊情怀哈哈哈哈哈哈哈哈...... 虽然我们平台业务上用的是Naive UI,不过我觉得UI框架大差不差啦auto-miniprogram-backend
nestjs 对于写惯前端来说没有别的后端语言经验的coder
来说简直是痛苦(ps: 我本人)
在做迁移的时候真的是痛苦到极致,不太会写,但是考虑到我们团队后端参与维护的情况下,选择了该框架(虽然但是这个配套的脚手架集成的能力是真香啊)
5. 未来期待
- 希望能将这个
miniprogram-ci
和这个小程序构建平台
并跑通ci全流程
给大伙开源做参考吧 - 持续完善和优化它们所具备的能力,包括不仅限于
- 接入各大
IM工具
的机器人能力
- 接入更多的
小程序平台
- 做更友好的
交互体验
6. 总结
至于为什么开源社区都有这么多现成工具可以使用却要自己重新写一个,一方面是为了自己学习,另一方面是要契合我们的业务需求和使用场景
- 也接触了
docker
和nginx配置
- 也使用
node
写了该平台的服务端 - 也对
ci
有了新的认知和了解
在今年的结尾也算对今年的自己有个交代,来年继续加油啦!!!!!!
7. 特别鸣谢
为作者的这个想法落地提供了大力支持