小程序打包方式分为两种:手动打包、自动打包
那如何实现 自动打包 呐?我们今天就来聊一聊!
首先,很重要,看 官方文档
这里提到今天我们要聊的“主角” miniprogram-ci
miniprogram-ci 是从微信开发者工具中抽离的关于小程序/小游戏项目代码的编译模块。
开发者可不打开小程序开发者工具,独立使用 miniprogram-ci 进行小程序代码的上传、预览等操作。
然后,我们 怎么做!!!
一:准备工作
使用 miniprogram-ci 前应访问"微信公众平台-开发-开发设置"后下载代码上传密钥(最终是需要放在项目根目录下的),并配置 IP 白名单 开发者可选择打开 IP 白名单,打开后只有白名单中的 IP 才能调用相关接口。
再者便是,需要在我们的项目中做好环境区分,即做好:测试环境 、预发环境、生产环境 等环境的区分
package.json 文件中代码如下所示:
ps:我们的小程序使用的是 Uni-App 开发的,因此代码打包命令行的前缀是 build:mp-weixin-xx 类似这样
二:下载包
npm install miniprogram-ci --save
三:项目根目录下编写脚本文件upload.js-实现自动化上传
直接上代码,有注释!(ps:不清楚的地方,我们评论区见~~)
const project_config = require("./project.config.json");
const child_process = require("child_process");
const ci = require("miniprogram-ci");
const inquirer = require("inquirer");
const request = require("request");
const fse = require("fs-extra");
const util = require("util");
const path = require("path");
const fs = require("fs");
const example = {
appid: "", // 小程序的appid
name: "", // 小程序的名字
choices: [
"测试环境3-test3",
"测试环境4-test4",
"预发环境-pre",
"演示环境-rep",
"生产环境-prod",
],
robot_1: 1, // 机器人 1 号
robot_2: 2, // 机器人 2 号
robot_3: 3, // 机器人 3 号
version: "1.0.0",
};
class appletCI {
exec = util.promisify(child_process.exec);
config = {};
// 流水线执行上传操作方法
async init() {
const result_data = await this.inquirer(project_config);
this.config = await this.update_config(result_data);
this.fs_rewrite_config();
await this.upload(result_data);
}
// 问答:选择环境、版本号、描述
async inquirer(config) {
return inquirer.prompt([
{
type: "list",
name: "env",
message: "请选择部署环境:",
default: 0,
choices: example.choices,
},
{
type: "input",
name: "version",
message: `设置上传的版本号(当前版本号:${config.version}):`,
filter(opts) {
if (opts === "") {
return config.version;
}
return opts;
},
},
{
type: "input",
name: "desc",
message: "请写一个简单的介绍来描述这个版本改动过:",
},
]);
}
// 更新配置信息
async update_config(user_info) {
const env = user_info.env.split("-")[1];
const env_desc = user_info.env.split("-")[0];
const config = {
appid: "", // 小程序的appid
name: "", // 小程序的名字
env,
env_desc,
version: user_info.version,
desc: user_info.desc || env_desc,
robot:
env === "prod" || env === "pre"
? example.robot_3
: env === "rep"
? example.robot_2
: example.robot_1,
};
return config;
}
// 重写配置文件
fs_rewrite_config() {
fs.writeFileSync(
"./project.config.json",
JSON.stringify(this.config),
(err) => {
if (err) {
console.log(
"自动写入 project.config.json 文件失败,请手动填写,并检查错误!"
);
}
}
);
}
// 打包上传
async upload() {
const {
appid: "", // 小程序的appid
name: "", // 小程序的名字
env = "test3",
env_desc = "测试环境3",
desc = "测试环境3",
robot = example.robot_1,
version = example.version,
} = this.config || {};
console.log(`${env_desc}正在打包`);
this.message(`${name}小程序-${env_desc},正在部署`);
await this.exec(`npm run build:mp-weixin-${env}`, { cwd: "./" });
await this.copyFiles();
console.log(`${env_desc}正在部署`);
const project = new ci.Project({
appid,
type: "miniProgram",
projectPath: path.join(__dirname, "./dist/build/mp-weixin"),
privateKeyPath: path.join(__dirname, "./private." + appid + ".key"),
ignores: ["node_modules/**/*", ".vscode", ".hbuilderx"],
});
await ci
.upload({
project,
robot,
desc,
version,
onProgressUpdate: console.log,
})
.then(() => {
this.message(`${name}小程序-${env_desc},部署完成`);
console.log("部署完成");
})
.catch((error) => {
if (error.errCode == -1) {
this.message(`${name}小程序-${env_desc},部署完成`);
console.log("部署完成");
return;
}
this.message(`${name}小程序-${env_desc},部署失败,原因为:${error}`);
console.log("部署失败", error);
process.exit(-1);
});
}
// 复制 project.config 文件至 dist
async copyFiles() {
try {
await fse.copy(
path.join(__dirname, "./project.config.json"),
path.join(__dirname, "./dist/build/mp-weixin/project.config.json")
);
} catch (err) {
console.error(err);
}
}
// 发送钉钉消息
message(content) {
const data = {
msgtype: "text",
text: { content },
};
request({
url: "", // 钉钉群里可以看到的webhook地址
method: "POST",
headers: {
"content-type": "application/json",
},
body: JSON.stringify(data),
});
}
}
const CI = new appletCI();
CI.init();
执行 :
node upload
执行完命令行的终端交互:
继续回车即可 自动化打包完成!
随后,我们去小程序管理后台拿到预览码即可
附录1:钉钉通知结果:
附录:2:钉钉的webhook地址如下图:
附录3:代码中有写到,自动化打包更改的 project.config.json 文件内容如下(每次打包后,该文件都会被更新):
{
"name":"",
"appid":"",
"env":"test3",
"env_desc":"测试环境3",
"version":"",
"desc":"",
"robot":1
}
再聊点其他的,提升点
鉴于在使用过程中获取体验码时,还需打开小程序管理后台获取验证码图片,未彻底解放双手,那么我们再去官方文档中扒拉扒拉,发现 preview 方法是专门实现预览功能滴,即,可实现:自动下载预览二维码图片至本地的某个路径!
具体可查看-预览模块如何实现:
至此,解放双手,happy end!!!