小程序批量化代码提交
提示:这里可以添加系列文章的所有文章的目录,目录需要自己手动添加
提示:写完文章后,目录可以自动生成,如何生成可参考右边的帮助文档
文章目录
前言
提示:这里可以添加本文要记录的大概内容:
工作中有上百个小程序需要提交代码,用开发工具操作太慢了,之前用开发工具做了批量上传,但是现在也会由于不知名原因中断,所以写了一个工具,便于平时代码提交。
找了各大论坛也没有支持多个小程序提交(部分帖子方案已经不适用)
提示:以下是本篇文章正文内容,下面案例可供参考
一、快速开始
本次使用微信小程序官方组件miniprogram-ci提交 微信小程序miniprogram-ci
项目结构:
二、使用步骤
1.小程序代码项目创建destroy文件夹
2.destroy文件夹下新增keys文件夹
前往微信小程序后台获取上传密钥,配置白名单
3. 上传小程序代码
代码如下(示例):upload.wx.js
const ci = require('miniprogram-ci');
const fs = require('fs');
const path = require('path');
// 接收主进程传递过来的参数
process.on('message', async (data) => {
let {appid, name, version, desc, env, appindex} = data
await setProjectConfig(appid);
await setConfig(appid);
const project = new ci.Project({
appid: appid,
type: 'miniProgram',
projectPath: path.resolve(__dirname, '../'),
privateKeyPath: path.resolve(__dirname,
`../destroy/keys/private.${appid}.key`),
ignores: ['node_modules/**/*', 'destroy/**/*'],
});
// 上传
const uploadResult = await ci.upload({
project,
version: version,
desc: desc,
setting: {
es6: true,
minifyJS: true,
minifyWXML: true,
minifyWXSS: true,
minify: true
},
onProgressUpdate: (e) => {
// console.log('onProcessUpdate', e)
if (e._status == "done" && e._msg == "upload") {
console.log(`${appid}--${name}--${env} 上传完成`);
// config.appindex += 1;
}
},
});
process.send('success');
process.exit();
});
// 设置 project.config.json
const setProjectConfig = async (appid) => {
// 读取和替换的文件路径
const project_config = '../project.config.json';
const promise = new Promise((resolve, reject) => {
// 读取 project.config.json
fs.readFile(
path.join(__dirname, project_config),
'utf8',
(err, data) => {
if (err) throw err;
let json = JSON.parse(data);
// 替换appid
json.appid = appid;
// console.log('project.config.json:', json)
// 改写 project.config.json 中 appid
fs.writeFile(
path.join(__dirname, project_config),
JSON.stringify(json, null, 4),
(err) => {
if (err) throw err;
resolve();
}
);
}
);
});
return promise;
}
// 设置config.js
const setConfig = async (appid) => {
// 读取和替换的文件路径
const config_file = '../config/config.js';
const promise = new Promise((resolve, reject) => {
// 读取 config.js
fs.readFile(
path.join(__dirname, config_file),
'utf8',
(err, data) => {
if (err) throw err;
let configjs = data;
const current_appid = appid;
// 替换文件中当前小程序的appid
const regex = new RegExp('(current_appid\\s*=\\s*["\']).*?(["\'])', 'g');
configjs = configjs.replace(regex, 'current_appid = \'' + current_appid + '\'');
// console.log(configjs)
// 改写 config.js 中 current_appid
fs.writeFile(
path.join(__dirname, config_file),
configjs,
(err) => {
if (err) throw err;
resolve();
}
);
}
);
});
return promise;
}
4.处理多个小程序循环
代码如下(示例):upload.main.js
const {fork} = require('child_process');
const fs = require('fs');
const path = require('path');
let config = {
appIds: [], // 小程序appid
version: "",//版本号
desc: "",//版本描述
env: '正式环境'
}
function publishMiniProgram(options) {
return new Promise((resolve, reject) => {
const child = fork('./destroy/upload.wx.js');
// console.log('入参:',options);
child.send(options);
child.on('message', (msg) => {
if (msg.error) {
reject(new Error(msg.error));
} else {
resolve(msg);
}
});
child.on('error', reject);
child.on('exit', (code) => {
if (code !== 0) {
reject(new Error(`child process exited with code ${code}`));
}
});
})
}
exports.start = async () => {
try {
const file = await fs.promises.readFile(
path.join(__dirname, '../destroy/config.json'),
'utf-8'
);
const fileJson = JSON.parse(file);
config = {
...config,
appIds: fileJson.appIds,
version: fileJson.version,
desc: fileJson.desc,
env: fileJson.env || '正式环境',
};
console.log(`本次提交小程序: ${config.appIds.map(item => `${item.name} (${item.appid})`).join(', ')}`);
console.log(`版本: ${config.version}`);
console.log(`环境: ${config.env}`);
console.log(`描述: ${config.desc}`);
// 3. 顺序发布(避免并发资源竞争)
let successCount = 0;
let failedCount = 0;
for (const [index, item] of config.appIds.entries()) {
try {
console.log(`\n开始发布第 ${index + 1} 个小程序: ${item.name} (${item.appid})`);
await publishMiniProgram({
appid: item.appid,
name: item.name,
version: config.version,
desc: `${config.env}——${config.desc}`,
env: config.env
});
successCount++;
console.log(`✅ 发布成功: ${item.name}`);
} catch (err) {
failedCount++;
console.error(`❌ 发布失败: ${item.name}`, err.message);
}
}
// 4. 返回统计结果
return {
success: successCount,
failed: failedCount,
};
} catch (e) {
console.error('❌ 启动发布流程失败:', e.message);
throw e;
}
}
5. 命令脚本
示例代码:upload_ci.js
const path = require('path');
const upload = require(path.join(__dirname, 'destroy/upload.main.js'))
;
(
async () => {
try {
const result = await upload.start();
console.log(`\n发布完成: 成功 ${result.success} 个, 失败 ${result.failed} 个`);
} catch (e) {
console.error('全局捕获错误:', e);
}
}
)();
6. 命令配置
示例代码:package.json
新增节点
"scripts": {
"upload": "node upload_ci.js"
}
7. 上传代码的配置项
示例代码:config.json
{
"version": "2.4.2",
"desc": "2.4.2 优化一些问题",
"appIds": [
{
"name": "xxxxxxx",
"appid": "xxxxxxxxx"
}
],
"env": "正式环境"
}
注意事项
· 本项目中使用到小程序APPID等信息的文件 project.config.json和config.js ,建议项目中减少其他文件直接写死appid。
· config.js文件中应用的当前appid的参数名改为“current_appid”(可根据自己的习惯定义)
// @config 确定使用的小程序appid
const current_appid = 'xxxxxxxxxxxxxxx';
总结
已实测40个小程序同时上传