记一下 uni-app 实现自动切换不同的地区环境及小程序配置
# 背景
最近接手了公司一个小程序项目,项目比较有特点:
- 开发、测试及生产环境各有一个
appid
- 有两个小程序会共用测试环境
- 测试环境与生产环境部分页面显示的文案略有不同
接手之前切换各环境采用手动修改代码的方式,比较繁琐容易漏改出错且不利于后续人员维护代码,非常影响开发体验。
# 优化方法
如果要切换小程序就需要动态修改 manifest.json 参数,通过分析文件结构:
{
...
"mp-weixin" : {
"appid": "wxe6fc48a27f7591b1",
...
},
...
}
可以知道我们只需要修改 appid
参数内容即可。
需要注意的是版本库中已经记录了一种环境下的配置,所以在我们修改之后在 git 会产生文件变更,需要我们在修改完配置打包编译成功之后再还原回默认环境配置,这样就不会让 git 检测到变更记录。
下面来介绍一下具体的改造过程。
- 添加环境变量配置文件。在项目根目录新建区分环境的 env 配置文件,例如
.env.xx
。
VUE_APP_ENV = '环境标识'
- 编译命令修改:
"build:mp-weixin-[环境名]-[小程序标识]": "cross-env NODE_ENV=uatProduction UNI_PLATFORM=mp-weixin vue-cli-service uni-build --mode [env配置文件名称] && node ./src/modifyManifest.js revert"
参数说明:
- [环境名]:由自己定义,可以区分打包到某个环境即可
- [小程序标识]:区分多个小程序中某个的标识,自定义即可
- [env 配置文件名称]:对应 1 中的 env 文件名(.env 后面部分)
- src 目录下创建文件
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");
最后执行我们定义的打包命令就可以实现动态切换环境及小程序 appid 了。
# 总结
本文目的提供了一种解放双手的思路,通过程序进行自动化来降低我们出错的概率,如果你也有同一个项目需要适配多个环境并且切换的小程序也不同的情况,可以参考并进行实践,希望对其他同学有所帮助。