2025年30多个小程序一键发布——miniprogram-ci

30多个小程序一键发布——miniprogram-ci概述 miniprogram ci 是从微信开发者工具中抽离的关于小程序 小游戏项目代码的编译模块 开发者可不打开小程序开发者工具 独立使用 miniprogram ci 进行小程序代码的上传 预览等操作 miniprogram ci 从 1 0 28 开始支持第三方平台开发的上传和预览 调用方式与普通开发模式无异 查看详情

大家好,我是讯享网,很高兴认识大家。

概述

miniprogram-ci 是从微信开发者工具中抽离的关于小程序/小游戏项目代码的编译模块。

开发者可不打开小程序开发者工具,独立使用 miniprogram-ci 进行小程序代码的上传、预览等操作。

miniprogram-ci 从 1.0.28 开始支持第三方平台开发的上传和预览,调用方式与普通开发模式无异。查看详情

密钥及 IP 白名单配置

使用 miniprogram-ci 前应访问"微信公众平台-开发-开发设置"后下载代码上传密钥,并配置 IP 白名单 开发者可选择打开 IP 白名单,打开后只有白名单中的 IP 才能调用相关接口。我们建议所有开发者默认开启这个选项,降低风险 代码上传密钥拥有预览、上传代码的权限,密钥不会明文存储在微信公众平台上,一旦遗失必须重置,请开发者妥善保管

入口
讯享网

功能

miniprogram-ci 目前提供以下能力:

  1. 上传代码,对应小程序开发者工具的上传
  2. 预览代码,对应小程序开发者工具的预览
  3. 构建 npm,对应小程序开发者工具的: 菜单-工具-构建npm
  4. 上传云开发云函数代码,对应小程序开发者工具的上传云函数能力
  5. 上传云托管代码,对应小程序开发者工具的上传云托管能力
  6. 上传云存储/静态托管文件,对应小程序开发者工具-云开发-云存储和静态托管文件管理
  7. 代理,配置 miniprogram-ci 的网络请求代理方式
  8. 支持获取最近上传版本的 sourceMap
  9. 支持 node 脚本调用方式和 命令行 调用方式

脚本调用

npm install miniprogram-ci --save 

讯享网

代码

preview.js

讯享网const ci = require('miniprogram-ci'); const fs = require('fs'); const path = require('path'); let config = { 
    xcxKey: [], //需要上传的小程序列表 version: "", //版本号 desc: "", //备注 appindex: 0 //当前执行到第几个 } exports.start = async () => { 
    //先拿到需要上传的列表,也就是小程序的appid和名称等相关信息,还有上传的版本和备注 fs.readFile( path.join(__dirname, '../xcxkey/xcxkey.json'), 'utf-8', (err, data) => { 
    const fileJson = JSON.parse(data) config.xcxKey = fileJson.xcxKey; config.version = fileJson.version; config.desc = fileJson.desc; config.env = fileJson.env; config.appindex = 0; console.log(`本次提交--${ 
    config.xcxKey.map(item=> config.env + item.desc + config.desc)}`); console.log(`版本--${ 
    config.version}`); previewStart(); } ); } const previewStart = async () => { 
    if (!config.xcxKey[config.appindex]) { 
    console.log('上传完成') return; } //开始上传,首先修改文件信息 await setProjectConfig(); await setMain(); console.log(`${ 
    config.xcxKey[config.appindex].desc}--${ 
    config.env}开始`); const project = new ci.Project({ 
    appid: config.xcxKey[config.appindex].appid, type: 'miniProgram', projectPath: path.resolve(__dirname, '../unpackage/dist/dev/mp-weixin'), privateKeyPath: path.resolve(__dirname, `../xcxkey/private.${ 
    config.xcxKey[config.appindex].appid}.key`), ignores: ['node_modules//*'], }); // 预览 const uploadResult = await ci.preview({ 
    project, version: config.xcxKey[config.appindex].version, desc: `${ 
    config.env}——${ 
    config.desc}`, setting: { 
    es6: true, minifyJS: true, minifyWXML: true, minifyWXSS: true, minify: true }, qrcodeFormat: 'image', qrcodeOutputDest: path.resolve(__dirname, `../ci/preview-images/${ 
    config.xcxKey[config.appindex].title}.jpg`), onProgressUpdate: getstate, pagePath: 'pages/home/index', // 预览页面 searchQuery: '' // 预览参数 [注意!]这里的`&`字符在命令行中应写成转义字符`\&` }); //监听上传过程,如果上传完成延迟10秒再上传下一个 function getstate(e) { 
    console.log('eeee', e); if (e._status === "done" && e._msg === "upload") { 
    console.log(`${ 
    config.xcxKey[config.appindex].desc}--${ 
    config.env}上传完成`) setTimeout(() => { 
    config.appindex += 1; previewStart(); }, 1000) } } } //修改 project.config.json 内容 const setProjectConfig = async () => { 
    // 要读取和替换的文件路径 const project_config = '../unpackage/dist/dev/mp-weixin/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 和 projectname json.appid = config.xcxKey[config.appindex].appid; json.projectname = config.xcxKey[config.appindex].name; // 改写 project.config.json 中 appid 和 projectname fs.writeFile( path.join(__dirname, project_config), JSON.stringify(json, null, 4), (err) => { 
    if (err) throw err; resolve(); } ); } ); }); return promise; } //修改 main.js 内容 const setMain = async () => { 
    // 要读取和替换的文件路径 const app_main_file = '../unpackage/dist/dev/mp-weixin/common/main.js'; const promise = new Promise((resolve, reject) => { 
    // 读取 unpackage/dist/dev/mp-weixin/common/main.js fs.readFile( path.join(__dirname, app_main_file), 'utf8', (err, data) => { 
    if (err) throw err; let app_main = data; const hotel_id = config.xcxKey[config.appindex].hotel_id; // 替换 source_hotel_id let re = /(?<=source_hotel_id:").*?(?=",source_hotel_id_end_ci:)/; app_main = app_main.replace(re, hotel_id); // 改写 unpackage/dist/dev/mp-weixin/common/main.js 中 source_hotel_id fs.writeFile( path.join(__dirname, app_main_file), app_main, (err) => { 
    if (err) throw err; resolve(); } ); } ); }); return promise; } 

upload.js

const ci = require('miniprogram-ci'); const fs = require('fs'); const path = require('path'); let config = { 
    xcxKey: [], //需要上传的小程序列表 version: "", //版本号 desc: "", //备注 env: "", appindex: 0 //当前执行到第几个 } exports.start = async () => { 
    //先拿到需要上传的列表,也就是小程序的appid和名称等相关信息,还有上传的版本和备注 fs.readFile( path.join(__dirname, '../xcxkey/xcxkey.json'), 'utf-8', (err, data) => { 
    const fileJson = JSON.parse(data) console.log(fileJson); config.xcxKey = fileJson.xcxKey; config.version = fileJson.version; config.desc = fileJson.desc; config.env = fileJson.env; config.appindex = 0; console.log(`本次提交--${ 
    config.xcxKey.map(item=> config.env + item.desc)} --- config.desc`); console.log(`版本--${ 
    config.version}`); uploadStart(); } ); } const uploadStart = async () => { 
    if (!config.xcxKey[config.appindex]) { 
    console.log('上传完成') return; } //开始上传,首先修改文件信息 await setProjectConfig(); await setMain(); console.log(`${ 
    config.xcxKey[config.appindex].desc}--${ 
    config.env}开始`); const project = new ci.Project({ 
    appid: config.xcxKey[config.appindex].appid, type: 'miniProgram', projectPath: path.resolve(__dirname, '../unpackage/dist/dev/mp-weixin'), privateKeyPath: path.resolve(__dirname, `../xcxkey/private.${ 
    config.xcxKey[config.appindex].appid}.key`), ignores: ['node_modules//*'], }); // 上传 const uploadResult = await ci.upload({ 
    project, version: config.xcxKey[config.appindex].version, desc: `${ 
    config.env}——${ 
    config.desc}`, setting: { 
    es6: true, minifyJS: true, minifyWXML: true, minifyWXSS: true, minify: true }, onProgressUpdate: getstate, }); console.log(uploadResult) //监听上传过程,如果上传完成延迟10秒再上传下一个 function getstate(e) { 
    if (e._status == "done" && e._msg == "upload") { 
    console.log(`${ 
    config.xcxKey[config.appindex].desc}--${ 
    config.env}上传完成`) setTimeout(() => { 
    config.appindex += 1; uploadStart(); }, 1000) } } } //修改 ext.json 内容 const setExtConfig = async () => { 
    // 要读取和替换的文件路径 const project_config = '../ext.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 和 projectname json.extAppid = config.xcxKey[config.appindex].appid; // 改写 project.config.json 中 appid 和 projectname fs.writeFile( path.join(__dirname, project_config), JSON.stringify(json, null, 4), (err) => { 
    if (err) throw err; resolve(); } ); } ); }); return promise; } //修改 project.config.json 内容 const setProjectConfig = async () => { 
    // 要读取和替换的文件路径 const project_config = '../unpackage/dist/dev/mp-weixin/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 和 projectname json.appid = config.xcxKey[config.appindex].appid; json.projectname = config.xcxKey[config.appindex].name; // 改写 project.config.json 中 appid 和 projectname fs.writeFile( path.join(__dirname, project_config), JSON.stringify(json, null, 4), (err) => { 
    if (err) throw err; resolve(); } ); } ); }); return promise; } //修改 main.js 内容 const setMain = async () => { 
    // 要读取和替换的文件路径 const app_main_file = '../unpackage/dist/dev/mp-weixin/common/main.js'; const promise = new Promise((resolve, reject) => { 
    // 读取 unpackage/dist/dev/mp-weixin/common/main.js fs.readFile( path.join(__dirname, app_main_file), 'utf8', (err, data) => { 
    if (err) throw err; let app_main = data; const hotel_id = config.xcxKey[config.appindex].hotel_id; // 替换 source_hotel_id let re = /(?<=source_hotel_id:").*?(?=",source_hotel_id_end_ci:)/; app_main = app_main.replace(re, hotel_id); // 改写 unpackage/dist/dev/mp-weixin/common/main.js 中 source_hotel_id fs.writeFile( path.join(__dirname, app_main_file), app_main, (err) => { 
    if (err) throw err; resolve(); } ); } ); }); return promise; } 

package.json

讯享网{ 
    "scripts": { 
    "upload": "node upload-ci.js", "preview": "node preview-ci.js" }, "dependencies": { 
    "gulp": "^4.0.2", "miniprogram-ci": "^1.8.12" } } 

在这里插入图片描述

preview-ci.js

 const path = require('path'); const preview = require(path.join(__dirname, './ci/preview')); ; (async () => { 
    preview.start(); })() 

upload-ci.js

讯享网 const path = require('path'); const upload = require(path.join(__dirname, './ci/upload')); ; (async () => { 
    upload.start(); })() 

在这里插入图片描述

{ 
    "xcxKey": [ { 
    "name": "名称", "title": "title", "appid": "appid", "version": "1.0.0", "desc": "备注" }, ... ], "env": "正式环境", "desc": "备注", "version": "1.0.0" } 
讯享网// npm run preview(会把xcxkey中的所有小程序打包预览) // npm run upload(会把xcxkey中的所有小程序打包提交体验版) 
小讯
上一篇 2025-03-29 09:57
下一篇 2025-03-15 08:51

相关推荐

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/66195.html