小程序代码批量上传

小程序批量化代码提交

提示:这里可以添加系列文章的所有文章的目录,目录需要自己手动添加


提示:写完文章后,目录可以自动生成,如何生成可参考右边的帮助文档


前言

提示:这里可以添加本文要记录的大概内容:

工作中有上百个小程序需要提交代码,用开发工具操作太慢了,之前用开发工具做了批量上传,但是现在也会由于不知名原因中断,所以写了一个工具,便于平时代码提交。
找了各大论坛也没有支持多个小程序提交(部分帖子方案已经不适用)


提示:以下是本篇文章正文内容,下面案例可供参考

一、快速开始

本次使用微信小程序官方组件miniprogram-ci提交 微信小程序miniprogram-ci

项目结构:
在这里插入图片描述

二、使用步骤

1.小程序代码项目创建destroy文件夹

2.destroy文件夹下新增keys文件夹

前往微信小程序后台获取上传密钥,配置白名单
微信小程序代码密钥和IP白名单配置

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个小程序同时上传

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值