前言
本文仅提供方案参考,如果有有误请指出,能帮上忙是我的荣幸,希望有大佬能指出更便捷的方法。 概念注释:文中的项目是指软件落地到不同的甲方产生的项目,工程是指手上的代码工程。
为啥要做项目切换
因为公司安排的开发了五个同类型项目,这五个项目大部分业务逻辑一致,有少部分有区分。如果用复制粘贴那将维护五套代码,所以尽量以维护一套代码并打包成多个项目且进行迭代。
从一下几个方面思考如何快速切换
便捷:最好是改一处,不改多处。 提效:尽量不打失误性的文件拷贝,导致重新打包。
需要解决什么问题
一套代码,多个项目,会意味着这一个工程中打包时面临不同配置参数,功能走向可能会有不同的页面展示或者不同的业务逻辑处理。如果以每次切换项目都是手动替换不同的manifest文件运行测试或者打包,这样勉强能用,但效率不高,且极易出错,一不小心就可能打错包,又要重新编译,浪费大量时间。
方案选型
1.用ifdef环境编译。比如项目A,就通过自定义ifdef A-app、ifdef A-mp,但这样以来,一个项目要是想输出多个平台,那又新增了工作量,这里要偷点懒。 2.改配置,不改代码。制定配置文件,在开发工具触发代码工程的编译时,去加载不同项目的配置文件,最终实现改一个参数就切换到了不同项目进行运行和打包。
上思路
1.设计配置文件,配置文件的内容主要就是每个项目中不同的参数配置项,首先就是依赖uniapp的manifest.json文件,其次每个项目中的服务器地址、特色功能配置提取、项目特定的全局颜色色系、苹果的套装id、隐私协议等等,这里我就用json格式去写,感觉比较直观。 2.何时加载,应该在项目运行初期就加载不同的配置文件。 3.如何加载,采用文件读取和写入操作进行。
场景环境模拟
目前手上的代码要打包成A、B、C、D、E五个项目。
上代码
1. 配置文件。
暂且分两部分,一部分是platformManifest用来存放每个项目的manifest.json,路径:YourProjectName/res/platformManifest。另一部分platformConfig存放每个项目的服务器等业务参数,路径:YourProjectName/res/platformConfig。
文件HC.A.json内容模板:
{
"platformName": "A项目",
"baseUrl": "yours base url",
"baseUrlNotes": "正式地址",
"betaUrl":"yours beta url",
"betaUrlNotes":"测试地址",
}
文件manifest.A.json内容模板,直接从manifest拷贝再进行,再进行内容改动: 注意:后续修改从此处修改,不从原有的mianfest文件中修改。
{
"name" : "A项目",
"appid" : "yours appid",
"description" : "",
"versionName" : "1.0.0",
"versionCode" : "100",
"transformPx" : false,
/* 5+App特有相关 */
"app-plus" : {
...
}
...
}
2. 控制面板,切换项目在此文件进行。
使用说明: platFormConfig.platFormKey为platFormKeyEnume.key值,这个值要与前面的HC.A.json和manifest.A.json 文件名中的A一致,作用是告诉加载器需要加载哪个文件。 PlatFormControl.json 文件内容为下,
{
"allNotes": "用户端平台全局配置控制文件",
"platFormConfigNotes": "动态修改manifest控制平台切换",
"platFormConfig": {
"platFormKeyNotes": "切换全局平台:粘贴platFormKeyEnume中的key值",
"platFormKey": "A",
"platFormKeyEnumeNotes": "列表中的每项key值必须与 ./res/platformConfig/ 下对应文件名‘.’中间部分相同。",
"platFormKeyEnume": [{
"keyNotes": "A项目",
"key": "A"
}, {
"keyNotes": "B项目",
"key": "B"
}, {
"keyNotes": "C项目",
"key": "C"
}, {
"keyNotes": "D项目",
"key": "D"
}, {
"keyNotes": "E项目",
"key": "E"
}]
},
"netRequestConfigNotes": "全局网络请求框架服务器地址控制",
"netRequestConfig": {
"baseUrlKeynNotes": "发行打包时执行,切换全局正式服务器地址(打包地址):粘贴serviceUrlKeyList中的key值",
"baseUrlKey": "baseUrl",
"betaUrlKayNotes": "运行时执行,切换全局测试服务器地址(直接安装地址):粘贴serviceUrlKeyList中的key值",
"betaUrlKay": "betaUrl",
"serviceUrlKeyNotes": "列表中的每项key值必须于 ./res/platformConfig/ 下对应的文件中存在。",
"serviceUrlKeyList": [{
"keyNotes": "正式服务器",
"key": "baseUrl"
}, {
"keyNotes": "公测地址",
"key": "betaUrl"
}]
}
}
3. 文件加载控制器,读取控制面板中的配置。
PlatformParamFileHelper.js 文件内容如下,不需要改动
const fs = require('fs')
let configFilePath = `${process.env.UNI_INPUT_DIR}/res/platformManifest/PlatFormControl.json`
let configFile = fs.readFileSync(configFilePath, { encoding: 'utf-8' })
/**
* 获取平台对应mianfest path key
*/
function getFileKey4PlatFormManifest() {
let _configFile = JSON.parse(configFile.toString())
// console.log("_configFile: " + JSON.stringify(_configFile));
// console.log("_configFile.platFormConfig.platFormKey: ",_configFile.platFormConfig.platFormKey);
return _configFile.platFormConfig.platFormKey
}
/* 文件key */
let platFormKey = getFileKey4PlatFormManifest()
/* process.env.UNI_INPUT_DIR为项目所在的绝对路径,经测试,相对路径会找不到文件 */
/* 对应平台manifest.json文件路径 */
let platFormFilePath = `${process.env.UNI_INPUT_DIR}/res/platformManifest/manifest.${platFormKey}.json`
// console.log("platFormFilePath: ",platFormFilePath);
/* 全局mianfest.json文件路径 */
let mainFilePath = `${process.env.UNI_INPUT_DIR}/manifest.json`
// console.log("mainFilePath: ",mainFilePath);
fs.readFile(platFormFilePath, function(err, data) {
if (err) {
console.error(`${platFormFilePath}读取失败`, JSON.stringify(err))
} else {
var _data = JSON.parse(data.toString())
_data = JSON.stringify(_data)
// console.log("modifyManifest.data: ",_data);
// 写入
fs.writeFile(
mainFilePath,
_data, {
encoding: 'utf-8'
},
function(err) {
if (err) {
console.error(`manifest动态修改结果:${platFormFilePath} 写入 ${mainFilePath} 失败`, err)
} else {
// console.warn(`manifest动态修改结果:${platFormFilePath} 写入 ${mainFilePath} 成功`)
console.warn(`manifest动态修改结果:manifest.${platFormKey}.json 写入 manifest.json 成功。`)
let platConfig = require(`${process.env.UNI_INPUT_DIR}/res/platformConfig/HC.${platFormKey}.json`)
// let modelManifestJson = require(`${process.env.UNI_INPUT_DIR}/res/platformManifest/manifest.${platFormKey}.json`)
// console.log("pConfig:", JSON.stringify(platConfig));
// console.log("modelManifestJson:", JSON.stringify(modelManifestJson));
let modelManifestJson = JSON.parse(_data)
let _configFile = JSON.parse(configFile.toString())
// let manifestJson = JSON
var urlKey = _configFile.netRequestConfig.baseUrlKey
let shopConfig = platConfig.shopConfig
if (process.env.NODE_ENV == "development") {
console.warn("当前环境: 运行环境(debug)");
urlKey = _configFile.netRequestConfig.betaUrlKay
if (shopConfig != null && shopConfig.devUrl != null) {
shopConfig = shopConfig.devUrl
}
} else {
urlKey = _configFile.netRequestConfig.baseUrlKey
console.warn("当前环境: 发行环境(Release)");
if (shopConfig != null && shopConfig.prodUrl != null) {
shopConfig = shopConfig.prodUrl
}
}
let url = platConfig[urlKey] || ''
console.warn('当前工程平台', platConfig.platformName);
console.warn('当前工程平台服务器地址', urlKey, ":", url)
console.warn('当前工程版本名称', modelManifestJson.versionName)
console.warn('当前工程版本号', modelManifestJson.versionCode)
}
}
)
}
})
4. 执行文件加载控制器。
在根目录下创建vue.config.js,文件内容:
let a = require("./res/platformManifest/PlatformParamFileHelper.js");
module.exports = {
}
5.测试
将你的项目跑起来,看看控制台日志测试吧。
运行会自动连接测试服务器
发行会自动连接正式服务器