【 uniapp中一工程多项目切换】

325 阅读4分钟

前言

本文仅提供方案参考,如果有有误请指出,能帮上忙是我的荣幸,希望有大佬能指出更便捷的方法。 概念注释:文中的项目是指软件落地到不同的甲方产生的项目,工程是指手上的代码工程。

为啥要做项目切换

因为公司安排的开发了五个同类型项目,这五个项目大部分业务逻辑一致,有少部分有区分。如果用复制粘贴那将维护五套代码,所以尽量以维护一套代码并打包成多个项目且进行迭代。

从一下几个方面思考如何快速切换

便捷:最好是改一处,不改多处。 提效:尽量不打失误性的文件拷贝,导致重新打包。

需要解决什么问题

一套代码,多个项目,会意味着这一个工程中打包时面临不同配置参数,功能走向可能会有不同的页面展示或者不同的业务逻辑处理。如果以每次切换项目都是手动替换不同的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.测试

将你的项目跑起来,看看控制台日志测试吧。

运行会自动连接测试服务器

运行会自动连接测试服务器

发行会自动连接正式服务器

在这里插入图片描述