需求背景

我们开发了一个分销商城平台,包含供应商和分销商两大角色。供应商将商品发布至平台后,分销商可购买付费功能,获得分销平台所有商品的权利,并能自定义加价。
购买该功能的分销商需要为其私域用户提供专属的二级域名网站和微信小程序,用于下单。这些渠道的展示信息(如首页风格、公司logo、联系电话、客服等)可由分销商自行配置。整体模式与SaaS服务类似,但功能定位不同。
当前痛点在于分销商的微信小程序均为独立注册。每当平台更新小程序功能时,需手动为每个分销商重新发布,工作量大且易出错。发布前还需修改配置文件,效率低下。因此,我们开发了自动化发布功能来解决这一问题。

前期准备
  • 服务器环境:Ubuntu 22.04.4 LTSNode.js v16.9.0Jenkins 2.504.3git 2.25.1java 17miniprogram-ci:^2.1.14
  • 开发Uniapp微信小程序的编辑器版本:HBuilderX 4.75
  • miniprogram-ci简介:miniprogram-ci 是微信官方从微信开发者工具中抽离的关于小程序/小游戏项目代码的编译模块。使用前需要使用小程序管理员身份访问"微信公众平台-开发-开发设置"后下载代码上传密钥,并配置 IP 白名单,才能进行上传、预览操作。
  • miniprogram-ci npm包的使用和介绍文档
完成整个流程需要掌握以下技能:
  • 1.Jenkins 的部署与使用,如果不了解可以查看我写的这篇文章<<Jenkins安装与部署教程>>
  • 2.HBuilderX 编辑器发行微信小程序代码
  • 3.node js 运行 js 脚本文件
一、配置环节
1.1、配置微信公众平台小程序代码上传
  • 登录微信公众平台,找到配置页面,节点位置:管理 > 开发管理 > 开发设置 小程序代码上传
    在这里插入图片描述
    小程序代码上传密钥:

    生成的密钥是一个.key后缀的文件,可以用记事本打开查看文件内容,内容如下:
    在这里插入图片描述

    IP白名单:

    IP白名单可以配置多个IP,这个值需要填写运行 miniprogram-ci 的服务器IP地址

二、发行Uniapp微信小程序代码包

我们使用 Uniapp 开发微信小程序使用的是 Vue.js 语法进行代码的编写,这个代码不能直接运行在微信小程序里,我们还需要借助 HbuilderX 编辑器来发行在微信小程序里面能运行的代码包。

  • HBuilderx 发行的代码包存放的位置
    使用编辑器的发行或运行功能后会在项目根目录下创建 dist 目录,这个目录存放的就是编译好的不同平台运行的代码包,在这个目录下有 builddev 两个子目录,两者的区别是: build 目录下的代码包用于生成环境,dev 目录下的代码包用于开发环境,并且dev 目录下的代码包体积比 build 目录下的体积大,这两个子目录下的 mp-weixin 存放的就是在微信小程序里面能运行的代码包。注意:每次使用发行或运行功能后会重新生成对应代码包,所以不要在代码包里面添加/修改文件,如有对应添加/修改需求,正确的做法是将代码包拷贝到新的目录再进行操作。代码包存放的位置如下图:
    在这里插入图片描述

  • 代码包大小要求
    官方说明文档
    微信官方要求是是单个分包/主包的大小不能超过2M,整个小程序分包大小不能超过30M。
    这里提一下踩的坑,HbuilderX 可以选择 运行发行 两种模式,这两种模式下生成的代码包大小有差异,如果是用微信开发者工具上传代码提交审核,我都是选择运行到小程序模拟器,很少用发行模式,两种模式生成的代码包大小差异可以在微信开发者工具里面查看:主包+分包大小显示如下:
    运行到微信小程序:
    在这里插入图片描述在这里插入图片描述
    从图中可以看到代码总体积是5.85MB主包大小为3.34MB已超过2MB大小限制,但是在微信开发者工具里面可以上传成功!

    发行模式:

    注意发行模式需要获取uni-app应用标识(AppID),这一步登录HBuilder账号,没有账号直接注册即可,完整步骤如下图:
    在这里插入图片描述在这里插入图片描述
    在这里插入图片描述
    发行模式生成的代码总体积为2.41MB主包1.51MB满足要求,相比运行模式生成的代码包减小了约50%。

    坑在哪里?

    一定要用发行的代码包,不要用运行模式的代码包miniprogram-ci 上传时如果代码包大小超过限制会报错,我就是一直用运行模式的代码包,导致主包大小超过2MB, miniprogram-ci 报错信息片段如下:

    CodeError: Error: {"errCode":-1,"errMsg":"inner upload fail with errcode: 80200, errmsg: main package source size 3439KB exceed max limit 2048KB"}
    at innerUpload (/wwww/artist/bin/weapp-packager/node_modules/miniprogram-ci/dist/ci/upload.js:1:4229)
    at processTicksAndRejections (node:internal/process/task_queues:96:5)
    at async upload (/wwww/artist/bin/weapp-packager/node_modules/miniprogram-ci/dist/ci/upload.js:1:1048)
    at async Object.<anonymous> (/wwww/artist/bin/weapp-packager/node_modules/miniprogram-ci/dist/utils/report.js:1:1490)
    at async /wwww/artist/bin/weapp-packager/index/index.js:10:24 {
    code: 20003
    }
    
三、编写调用 miniprogram-ci js脚本

有了代码包和微信官方的 miniprogram-ci 再结合Jenkins就可以实现自动上传代码包到对应微信小程序了, Jenkins 配置拉取代码包仓库和运行指定脚本这部分可以参考我写的这篇<<Jenkins安装与部署教程>>,上传代码包的核心是运行 miniprogram-ci js脚本,脚本内容如下:

console.log('Arguments:', process.argv);
const options = process.argv.slice(2);
const configs = Object.fromEntries(options.map(item => item.split('=')));

const {appid,projectPath,privateKeyPath,version,desc} = configs;

const ci = require('miniprogram-ci');
;(async () => {
 const project = new ci.Project({
   appid: appid,
   type: 'miniProgram',
   projectPath: projectPath,
   privateKeyPath: privateKeyPath,
   ignores: ['node_modules/**/*'],
   setting: {
     es6: true,
     minify: true,
   }
 })
 const uploadResult = await ci.upload({
   project,
   version: version,
   desc: desc,
   onProgressUpdate: console.log,
 })
 console.log(uploadResult)
})();

执行这个js脚本的命令:

node /wwww/artist/bin/weapp-packager/index/index.js appid=wx888888ec projectPath=/var/lib/jenkins/workspace/weapp_code privateKeyPath=/wwww/artist/bin/weapp-packager/private.wx888888ec.key version=2.0.23 desc=版本说明

这个脚本代码其实不复杂,只需要接受命令参数,初始化项目,调用 miniprogram-ciupload方法上传即可,脚本代码步骤分析:

1. 获取命令行参数

console.log('Arguments:', process.argv);
const options = process.argv.slice(2);//获取命令行参数以空格分隔为数组,这里用slice提取数组,去掉第[0]、[1]项数据:node和/wwww/artist/bin/weapp-packager/index/index.js
const configs = Object.fromEntries(options.map(item => item.split('=')));
  • 作用:解析命令行传入的键值对参数(如 appid=wx888888ec)并转换为对象。

  • 处理结果

    {
      appid: 'wx888888ec',
      projectPath: '/var/lib/jenkins/workspace/weapp_code',
      privateKeyPath: '/wwww/artist/bin/weapp-packager/private.wx888888ec.key',
      version: '2.0.23',
      desc: '版本说明'
    }
    

2. 解构配置对象

const {appid, projectPath, privateKeyPath, version, desc} = configs;
  • 作用:将配置对象中的字段解构出来,便于后续使用。

3. 引入 miniprogram-ci 模块

const ci = require('miniprogram-ci');
  • 说明miniprogram-ci 是微信官方提供的小程序自动化工具包,支持构建、上传、预览等操作。

4. 创建小程序项目对象

const project = new ci.Project({
  appid: appid,
  type: 'miniProgram',
  projectPath: projectPath,
  privateKeyPath: privateKeyPath,
  ignores: ['node_modules/**/*'],
  setting: {
    es6: true,
    minify: true,
  }
});
  • 参数说明

    • appid: 小程序 AppID;
    • type: 类型,这里是 miniProgram
    • projectPath: 项目本地路径(项目指的是HBuilderX发行的微信小程序代码包,Jenkin拉取代码包仓库代码后会存放在var/lib/jenkins/workspace/这个目录下,Jenkins会根据任务名称创建对应子目录,所以要填写对,这里我传递的是/var/lib/jenkins/workspace/weapp_code这个路径,如果代码包放在其他目录,传递对应目录就行。);
    • privateKeyPath: 私钥路径(私钥就是配置环节提到的小程序代码上传密钥.key文件,需要传递完整路径,这里我传递的是:/www/artist/bin/weapp-packager/private.wx888888ec.key);
    • ignores: 忽略上传的文件或目录;
    • setting: 构建设置:
      • es6: 是否启用 ES6 转 ES5;
      • minify: 是否压缩代码(一定要设置为true,不然有可能报代码包大小超出2M限制的错误)。
  • 官方参数说明
    在这里插入图片描述

  • 更多参数介绍和用法自行查看这个官方文档

5. 上传小程序

const uploadResult = await ci.upload({
  project,
  version: version,
  desc: desc,
  onProgressUpdate: console.log,
});
  • 参数说明
    • project: 上一步创建的项目对象;
    • version: 上传版本号;
    • desc: 上传描述;
    • onProgressUpdate: 上传进度回调函数。

6. 输出上传结果

console.log(uploadResult);
  • 作用:打印上传结果信息,如成功或失败状态、错误信息等。
注意事项
  1. 私钥文件privateKeyPath 指向的文件需要是微信小程序管理后台下载的私钥文件;
  2. 依赖安装:确保已经安装了 miniprogram-ci 包:
    npm install miniprogram-ci
    
  3. Node.js 环境:需要运行在 Node.js 环境中。
四、使用Jenkins 拉取代码包仓库并运行 miniprogram-ci js脚本

在这里插入图片描述
在这里插入图片描述

上传成功输出的信息如下:
[info] useCOS parameter:  undefined
[info] upload zip buffer size:  1140966
[info] request url: https://servicewechat.com/wxa/ci/upload?codeprotect=0&type=miniProgram&appid=wx888888ec &version=0.0.1&desc=miniprogram-ci%20commit&robot=1&debugLaunchInfo=%7B%22scene%22%3A1011%7D
{
  id: '0.28490440912694991751350000000',
  message: 'upload',
  status: 'done'
}
{
  subPackageInfo: [
    { name: '/listPackage/', size: 358621 },
    { name: '/orderPackage/', size: 338178 },
    { name: '/userPackage/', size: 339043 },
    { name: '__APP__', size: 1442309 },
    { name: '__FULL__', size: 2478151 }
  ],
  pluginInfo: [],
  devPluginId: undefined
}

上传失败输出的信息如下:

失败时注意看输出的错误信息,以下错误是代码包大小超过2M限制,这个时候需要考虑怎么缩小代码包体积,如果是其他错误根据提示自己定位错误原因。

CodeError: Error: {"errCode":-1,"errMsg":"inner upload fail with errcode: 80200, errmsg: main package source size 3439KB exceed max limit 2048KB"}
    at innerUpload (/wwww/artist/bin/weapp-packager/node_modules/miniprogram-ci/dist/ci/upload.js:1:4229)
    at processTicksAndRejections (node:internal/process/task_queues:96:5)
    at async upload (/wwww/artist/bin/weapp-packager/node_modules/miniprogram-ci/dist/ci/upload.js:1:1048)
    at async Object.<anonymous> (/wwww/artist/bin/weapp-packager/node_modules/miniprogram-ci/dist/utils/report.js:1:1490)
    at async /wwww/artist/bin/weapp-packager/index/index.js:10:24 {
  code: 20003
	}
上传成功后可以到微信公众平台-小程序里面查看和提交审核,显示如下图:

在这里插入图片描述

Logo

一站式 AI 云服务平台

更多推荐