微信小程序多环境打包发布配置
大约 4 分钟约 1075 字
通过读写 manifest.json 等文件实现动态配置化
1.src 目录下创建文件 modifyManifest.js,写入如下内容:
// modifyManifest.js
const fs = require('fs')
//此处如果是用HBuilderX创建的项目manifest.json文件在项目跟目录,如果是 cli 创建的则在 src 下,这里要注意
//process.env.UNI_INPUT_DIR为项目所在的绝对路径,经测试,相对路径会找不到文件
const revert = process.argv[process.argv.length - 1]
// 根据还原参数区分使用原路径(最后执行命令的时候已经没有UNI全局变量了)
const root = revert == 'revert' ? 'src' : process.env.UNI_INPUT_DIR
const manifestPath = root + '/manifest.json'
let Manifest = fs.readFileSync(manifestPath, {
encoding: 'utf-8'
})
// pages/index/index.vue 文件修改
const pageIndexPath = root + '/pages/index/index.vue'
let pageIndex = fs.readFileSync(pageIndexPath, {
encoding: 'utf-8'
})
function replaceManifest(path, value) {
const arr = path.split('.')
const len = arr.length
const lastItem = arr[len - 1]
let i = 0
let ManifestArr = Manifest.split(/\n/)
for (let index = 0; index < ManifestArr.length; index++) {
const item = ManifestArr[index]
if (new RegExp(`"${arr[i]}"`).test(item)) ++i
if (i === len) {
const hasComma = /,/.test(item)
ManifestArr[index] = item.replace(
new RegExp(`"${lastItem}"[\\s\\S]*:[\\s\\S]*`),
`"${lastItem}" : ${value}${hasComma ? ',' : ''}`
)
break
}
}
Manifest = ManifestArr.join('\n')
}
// 动态配置appid
if (process.env.VUE_APP_ENV === 'A环境标识参数') {
// A环境
replaceManifest('mp-weixin.appid', '"A环境appid"')
fs.writeFileSync(pageIndexPath, pageIndex.replace('文案B', '文案A'), {
flag: 'w'
})
} else if (process.env.VUE_APP_ENV === 'B环境标识参数') {
// B环境
replaceManifest('mp-weixin.appid', '"B环境appid"')
fs.writeFileSync(pageIndexPath, pageIndex.replace('文案A', '文案B'), {
flag: 'w'
})
} else {
// C环境
replaceManifest('mp-weixin.appid', '"C环境appid"')
}
const lastParam = process.argv[process.argv.length - 1]
if (lastParam == 'revert') {
// 还原appid
replaceManifest('mp-weixin.appid', '"默认appid"')
// 文案还原
fs.writeFileSync(pageIndexPath, pageIndex.replace('环境下文案', '默认文案'), {
flag: 'w'
})
}
fs.writeFileSync(manifestPath, Manifest, {
flag: 'w'
})
- 在 vue.config.js 中引入。
require('./src/modifyManifest.js')
接入 miniprogram-ci
1. 简介
miniprogram-ci 是从微信开发者工具中抽离的关于小程序/小游戏项目代码的编译模块。开发者可不打开小程序开发者工具,独立使用 miniprogram-ci 进行小程序代码的上传、预览等操作。
- 文档:https://www.npmjs.com/package/miniprogram-ci
2. 平台设置
使用 miniprogram-ci 前应在微信公众平台登录小程序,访问“开发-开发管理-开发设置”后下载“代码上传密钥”,并配置 IP 白名单。
开发者可选择打开 IP 白名单,打开后只有白名单中的 IP 才能调用相关接口。
代码上传密钥拥有预览、上传代码的权限,密钥不会明文存储在微信公众平台上,一旦遗失必须重置,请开发者妥善保管
3. 脚本调用:
npm install miniprogram-ci --save
4. 项目对象
const ci = require('miniprogram-ci')
// 注意: new ci.Project 调用时,请确保项目代码已经是完整的,避免编译过程出现找不到文件的报错。
const project = new ci.Project({
appid: 'appid',
type: 'miniProgram',
projectPath: 'the/project/path',
privateKeyPath: 'the/privatekey/path',
ignores: ['node_modules/**/*']
})
上传代码
const ci = require('miniprogram-ci')
;(async () => {
const project = new ci.Project({
appid: 'wxsomeappid',
type: 'miniProgram',
projectPath: 'the/project/path',
privateKeyPath: 'the/path/to/privatekey',
ignores: ['node_modules/**/*']
})
const uploadResult = await ci.upload({
project,
version: '1.1.1',
desc: 'hello',
setting: {
es6: true
},
onProgressUpdate: console.log
})
console.log(uploadResult)
})()
详细参数配置,见文档:https://developers.weixin.qq.com/miniprogram/dev/devtools/ci.html
5.实际使用
看下目录结构:下面 2 个 key 是不同 appid 环境的代码上传秘钥
我们主要看下 autoUpload.js
// 自动将代码上传到小程序
const ci = require('miniprogram-ci')
const path = require('path')
const mainfest = require('../src/manifest.json')
const slog = require('single-line-log').stdout
const robot = Number(process.env.ROBOT) || 1
const buildVersion =
process.env.npm_config_build_version || mainfest.versionName
function getUploadDesc() {
// dev
if (robot === 1) {
return 'build by robot --dev'
}
// test
if (robot === 2) {
return 'build by robot --test'
}
// release
if (robot === 3) {
return 'build by robot --release'
}
// uat
if (robot === 4) {
return 'build by robot --uat'
}
return mainfest.description
}
async function main() {
const project = new ci.Project({
appid: mainfest['mp-weixin'].appid, //appid
type: 'miniProgram',
projectPath: path.resolve(__dirname, '../dist/build/mp-weixin'), //项目路径
privateKeyPath: path.resolve(
__dirname,
`./private.${mainfest['mp-weixin'].appid}.key`
), //小程序后台的上传密匙
ignores: ['node_modules/**/*']
})
let slogIndex = 0
try {
await ci.upload({
project,
version: buildVersion,
desc: getUploadDesc(),
setting: mainfest['mp-weixin'].setting,
robot,
onProgressUpdate: () => {
slog(
'上传中' +
(slogIndex === 0 ? '.' : slogIndex === 1 ? '..' : '...') +
'\n'
)
slogIndex++
if (slogIndex === 3) {
slogIndex = 0
}
}
})
console.log(`上传成功 版本${buildVersion}`)
} catch (error) {
console.error(`上传失败 版本${buildVersion}`, error)
}
}
main()
我们还有个 prebuild.js 用于不同的环境设置不同的 appid
const fs = require('fs')
const process = require('process')
function outputManifest() {
const manifest = require('../src/manifest.json')
manifest['mp-weixin'].appid =
process.env.BUILD_ENV === 'uat' ? 'wx***' : 'wx***'
fs.writeFileSync(
'./src/manifest.json',
JSON.stringify(manifest, null, 2) + '\n',
'UTF-8'
)
}
outputManifest()
那么在 package.json 的 scripts 设置命令如下
{
"script": {
"build-dev": "cross-env BUILD_ENV=dev node ./ci/prebuild.js && cross-env NODE_ENV=production UNI_PLATFORM=mp-weixin vue-cli-service --mode dev uni-build --minimize && cross-env ROBOT=1 node ./ci/autoUpload.js"
}
}