uni-app自定义多环境配置,动态修改appid
背景
在企业级项目开发中,一般都会分为开发、测试、预发布、生产等多个环境,在工程化中使用不同的打包命令改变环境变量解决不同环境各种变量需要手动修改的问题,比如接口请求地址,不同环境的请求路径前缀都是不同的。在使用uni-app
开发项目时,一般都是选择使用HbuilderX
可视化创建项目,也不建议使用cli
工程化方式创建uni-app
项目。在HbuilderX
中,默认只支持开发和生产两个环境,点击“运行”编译出来的代码是开发环境(development
),点击“发行”编译出来的代码是生产环境(production
),可以通过process.env.NODE_ENV
获取当前环境。但在很多企业中,可能就2个环境并不能满足实际场景,同时在开发微信小程序时,测试和生产都是不同的appid
,每次部署都要手动修改切换很容易出现问题。为了解决上述问题,通过在package.json
中增加uni-app
扩展节点,实现自定义条件编译平台,让每种编译具有不同环境标识。再扩展vite.config.js
配置文件,用环境标识判断重写文件中的appid
。
解决方案
一、创建基础项目
选择默认模板,注意vue版本选择3
二、增加扩展节点
根据官方文档说明,扩展节点配置说明如下:
{/*** package.json其它原有配置 * 拷贝代码后请去掉注释!*/"uni-app": {// 扩展配置"scripts": {"custom-platform": { //自定义编译平台配置,可通过cli方式调用"title":"自定义扩展名称", // 在HBuilderX中会显示在 运行/发行 菜单中"browser":"", //运行到的目标浏览器,仅当UNI_PLATFORM为h5时有效"env": {//环境变量"UNI_PLATFORM": "", //基准平台"MY_TEST": "", // ... 其他自定义环境变量},"define": { //自定义条件编译"CUSTOM-CONST": true //自定义条件编译常量,建议为大写}}}}
}
注意:
UNI_PLATFORM
仅支持填写uni-app
默认支持的基准平台,目前仅限如下枚举值:h5
、mp-weixin
、mp-alipay
、mp-baidu
、mp-toutiao
、mp-qq
browser
仅在UNI_PLATFORM
为h5
时有效,目前仅限如下枚举值:chrome
、firefox
、ie
、edge
、safari
、hbuilderx
package.json
文件中不允许出现注释,否则扩展配置无效vue-cli
需更新到最新版,HBuilderX需升级到 2.1.6+
实际使用时,暂时不用的变量直接删除,新建package.json
文件,代码如下:
{"uni-app": {"scripts": {"wx-test": {"title":"微信小程序 测试环境","env": {"UNI_PLATFORM": "mp-weixin","NAME": "test"}},"wx-prod": {"title":"微信小程序 生产环境","env": {"UNI_PLATFORM": "mp-weixin","NAME": "production"}},"h5-dev": {"title":"H5 开发环境","browser":"chrome","env": {"UNI_PLATFORM": "h5","NAME": "development"}},"h5-test": {"title":"H5 测试环境","browser":"chrome","env": {"UNI_PLATFORM": "h5","NAME": "test"}},"h5-prod": {"title":"H5 生产环境","browser":"chrome","env": {"UNI_PLATFORM": "h5","NAME": "production"}}}}
}
上面代码片段只以微信小程序和H5
两个端为例,其中只增加了常量NAME
用于区分当前环境,类似于process.env.NODE_ENV
获取环境变量的作用。一般小程序也就测试和生产两个环境,环境太多都要重新申请账号也麻烦。H5
按照常规的配置本地开发、测试、生产三个环境。配置好后我们点击顶部菜单栏的“运行”和“发行”即可看到效果。
当在业务里需要使用添加的NAME
变量时,直接通过process.env.NAME
即可获取。
四、配置其他变量
根目录下新建config
目录,用于放一些业务配置项,再新建环境相关变量配置文件env.js
,代码如下:
// 不同的环境变量配置
const development = {requestBaseUrl: 'http://development', appid: '',
}const test = {requestBaseUrl: 'http://test',appid: 'wxd5xxxxee0fce1c81',
}const production = {requestBaseUrl: 'http://production',appid: 'wx3xxxx1ce403cab3',
}export default {development,test,production
}
其中变量对象名称development
、test
、production
要和package.json
文件中定义的NAME
保持一致,方便后续通过对象方式直接取值。变量对象中添加的是需要根据不同环境配置的变量,比如后端服务请求地址,小程序appid
和一些别的插件key
。配置后我们就可以配合环境NAME
获取到不同环境的其他变量了,简单使用方式如下:
import ENV_CONFIG from '@/config/env.js'
console.log(ENV_CONFIG[process.env.NAME].requestBaseUrl) // 运行H5 开发环境结果 http://development
每次引入获取方式肯定不够友好,在uni-app
中还可以通过修改vite
配置添加全局变量,更方便在全局使用。
首先根目录下新建vite.config.js
文件,内容如下:
import { defineConfig } from 'vite'
import uni from '@dcloudio/vite-plugin-uni'
import ENV_CONFIG from './env/index.js'export default defineConfig({plugins: [uni()],define: {'process.env.config': ENV_CONFIG,},
});
通过定义一个全局变量process.env.config
,赋值为ENV_CONFIG
,process.env.config
可以改为任何一个字符串,这里主要是为了保持和默认通过process.env
获取环境变量的语义一致性。此时使用时就无需在业务中单独引入,从全局对象process.env.config
上取值即可:
console.log(process.env.config[process.env.NAME].requestBaseUrl) // 运行H5 开发环境结果 http://development
五、动态修改小程序appid
appid
是在根目录下的manifest.json
文件中,点击后最下面有源码视图。修改的方式就是运用node
的fs
模块,先读取manifest.json
文件,然后根据当前环境,动态替换掉appid
或者其他参数,最后重新写入到当前目录下。具体也是在vite.config.js
中处理:
import { defineConfig } from 'vite';
import uni from '@dcloudio/vite-plugin-uni';
import ENV_CONFIG from './config/env.js'// 引入fs模块
import fs from 'fs'// 读取 manifest.json ,修改后重新写入
const manifestPath = `${__dirname}/manifest.json`;
let Manifest = fs.readFileSync(manifestPath, { 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}": ${typeof value === 'string'? '"'+value+'"' : value}${hasComma ? ',' : ''}`);break;}}Manifest = ManifestArr.join('\n');
}
// 具体使用,找到对应key值替换为新的值
// replaceManifest('app-plus.usingComponents', false);const appid = ENV_CONFIG[JSON.parse(process.env.UNI_CUSTOM_DEFINE).NAME].appid
replaceManifest('mp-weixin.appid', appid);fs.writeFileSync(manifestPath, Manifest, { flag: 'w' });export default defineConfig({plugins: [uni()],define: {'process.env.config': ENV_CONFIG,},
});
这个修改方案是根据官方提供的代码片段修改,其中进行了一些变动:
manifest.json
文件路径由相对路径改为__dirname
获取的绝对路径replaceManifest
方法中的value进行了typeof
类型判断,如果是字符串加上双引号。因为测试时传个字符串会替换成没引号的变量或者数字
同时关于当前环境变量的获取,此时通过process.env.NAME
是获取不到package.json
配置的NAME
的,通过打印process.env
可以发现此时它是个包含很多变量的json
,在UNI_CUSTOM_DEFINE
下面是可以找到NAME
,这样就能根据不同环境获取不同的appid
。
然后也可以用下面这种更容易理解的方式修改manifest.json
,但是修改后内容排在一行,想要美观还需要手动格式化。
// appid获取只做参考,这里只是说明简单的只有两个环境,可以直接取process.env.NODE_ENV判断
let appid = process.env.NODE_ENV == "production" ? '生产的appid' : "开发的appid"
// manifest.json 路径
let manifestFileUrl = `${__dirname}/manifest.json`
// 读取文件数据
let manifestFileData = fs.readFileSync(manifestFileUrl, { encoding: 'utf8' });
// 移除// 和 /* */注释
manifestFileData = manifestFileData.replace(/\\"|"(?:\\"|[^"])*"|(\/\/.*|\/\*[\s\S]*?\*\/)/g, (m, g) => g ? "" : m)
// // 将txt转成obj
let manifestFileDataObj = JSON.parse(manifestFileData)
// 修改指定key对应的valuemanifestFileDataObj['mp-weixin']['appid'] = appid
// 把修改后的对象以json写入文件
fs.writeFileSync(manifestFileUrl, JSON.stringify(manifestFileDataObj), { encoding: 'utf8' })
六、使用方式
- 需要本地调试时,点击工具栏“运行”,选择自定义的对应开发或测试环境;
- 业务中通过
process.env.config[process.env.NAME]
获取配置的变量对象; - 上线时,点击工具栏“发行”,选择自定义的对应测试或生产环境;
运行环境
以上代码是运行在Hbuilderx 3.7.9
版本,项目为vue3
版本,基于vite
构建。如在vue2
版本上使用,请按照vite.config.js
逻辑自行探索配置vue.config.js
文件。
相关文章:

uni-app自定义多环境配置,动态修改appid
背景 在企业级项目开发中,一般都会分为开发、测试、预发布、生产等多个环境,在工程化中使用不同的打包命令改变环境变量解决不同环境各种变量需要手动修改的问题,比如接口请求地址,不同环境的请求路径前缀都是不同的。在使用uni-…...

04 - 分离头指针情况、理解HEAD和branch
查看所有文章链接:(更新中)GIT常用场景- 目录 文章目录 1. 分离头指针2. HEAD和branch2.1 branch的一些操作2.2 HEAD 1. 分离头指针 分离头指针detached HEAD是一种HEAD指针指向了某一个具体的 commit id,而不是分支的情况。 切换…...

C#__基本特性和使用
// 特性(attribute): // 一种允许我们向程序集添加元数据的语言结构 // 用于保存程序结构信息的某种特殊类型的类 // 类似“批注”,用于解释说明 #define IsShowMessage // 宏定义,在开头定义࿰…...
mysql(3)
分库分表 分库:将数据库中的数据分散到不同数据库上,可以垂直分库和水平分库。 1.垂直分库:把单一的数据按照业务进行划分,不同的业务使用不同的数据库,进而将一个数据库的压力分散到多个数据库。 2.水平分库&#…...
阿里巴巴常用的12个后端开发工具
1 阿尔萨斯Java在线诊断工具 Arthas是一款用于Java应用程序的在线诊断工具,由阿里巴巴于2018年9月开源。 典型场景: 您不知道从中加载类的特定JAR包。 您想弄清楚为什么您的系统会抛出各种与类相关的异常。 您不知道为什么修改后的代码无法执行。您不…...

php base64转图片保存本地
调用函数 public function base64(){$img $this->request->param(img);$img data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAkACQAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAxNDQ0Hyc5PTgyPC4zNDL/2wBDAQkJCQwLDBgNDRgyIRwhMjIyMjIy…...

unity物体移动至指定位置
物体坐标与物体移动 世界坐标与局部坐标之间的转换物体移动至指定位置需求思路注意 世界坐标与局部坐标之间的转换 在Unity中,物体的坐标分为局部坐标和世界坐标。 局部坐标是相对于物体的父对象的坐标系,而世界坐标是相对于场景的整体坐标系。 使用tr…...

详解C#-static void Main(string[] args)
目录 简介: 举例: 输出结果:编辑 总结: 简介: 在C#中static void Main(string[] args)这个句话有什么作用,分别代表什么意思!! 这句话是入口函数的声明,指定了C#程序的入口点,并定义了一个名为”Mai…...

中大许少辉博士《乡村振兴战略下传统村落文化旅游设计》中国建筑工业出版社八一付梓。
中大许少辉博士《乡村振兴战略下传统村落文化旅游设计》中国建筑工业出版社八一付梓。...

Matplotlib数据可视化(五)
目录 1.绘制折线图 2.绘制散点图 3.绘制直方图 4.绘制饼图 5.绘制箱线图 1.绘制折线图 import matplotlib.pyplot as plt import numpy as np %matplotlib inline x np.arange(9) y np.sin(x) z np.cos(x) # marker数据点样式,linewidth线宽,li…...
Python爬虫——requests_post请求
import requests import jsonurl https://fanyi.baidu.com/sugheaders {User-Agent: ,Cookie: }data {kw: hello }response requests.post(url, data, headersheaders)content response.textobj json.loads(content.encode(utf-8)) print(obj)总结: post请求…...

excel 下载方法封装
1.首先需要拿到后端返回的URL下载地址 2.写个下载方法 // url 接口返回的下载地址。例如:https://cancer-research.oss-cn-beijing.aliyuncs.com/yuance-platform-permission/校内共享数据导入模板.xlsx // name 文件名称 例如: 校内共享数据导入模板 /…...
按日,周,月,季,年统计;获取对应的时间段
按日,周,月,季,年统计;获取对应的时间段 1.周实体类:WeekEntity.java package com.test.common.entity;import java.time.LocalDate;public class WeekEntity {private String day;/*** 开始日期**/privat…...

【eNSP】交换机(vlan和vlan间通信)
【eNSP】交换机(vlan和vlan间通信) 原理术语过程 实验根据图片连接模块配置设备名称和IP地址配置交换机交换机链路指定sw1配置sw2配置 设置网关交换机互联实验设置查看设置结果 ospf配置 原理 HUB集线器:它的作用可以简单的理解为将一些机器…...

2011年下半年 软件设计师 上午试卷2
博主介绍:✌全网粉丝3W,全栈开发工程师,从事多年软件开发,在大厂呆过。持有软件中级、六级等证书。可提供微服务项目搭建与毕业项目实战,博主也曾写过优秀论文,查重率极低,在这方面有丰富的经验…...
Linux中安装MySQL8版本,安装MySQL步骤,MySQL8离线安装
Linux中安装MySQL8版本的步骤如下: 1.检查下libaio.so.1的位置 [roottdx ]# whereis libaio.so.1 libaio.so: /usr/lib64/libaio.so.1 如果没有找到该文件 (1).在线安装 [roottdx ]# yum install -y libaio (2).离线安装: 上传之后执行命令安装&#…...

MES生产管理系统如何与ERP系统集成
MES生产管理系统和ERP企业管理系统是制造企业信息化的重要组成部分,它们在生产管理、资源计划和业务流程等方面发挥着重要作用。实现MES与ERP系统的集成,可以更好地优化企业生产流程,提高生产效率和降低成本。本文将探讨MES管理系统解决方案如…...
Kafka如何保证消息⼀定能被消费
Kafka 通过多种机制来保证消息一定能被消费,从而实现数据的可靠性和持久性。 以下是一些常见的方法和策略来提高消息的可靠性: 复制机制: Kafka 使用了分区和副本的概念。每个分区可以有多个副本,分布在不同的 Broker 上。当消息…...

[USACO1.5] 八皇后 Checker Challenge
题目描述 一个如下的 6 x 6 的跳棋棋盘,有六个棋子被放置在棋盘上,使得每行、每列有且只有一个,每条对角线(包括两条主对角线的所有平行线)上至多有一个棋子。 上面的布局可以用序列 2 4 6 1 3 5 来描述,第…...

【Mysql】MVCC版本机制的多并发
🌇个人主页:平凡的小苏 📚学习格言:命运给你一个低的起点,是想看你精彩的翻盘,而不是让你自甘堕落,脚下的路虽然难走,但我还能走,比起向阳而生,我更想尝试逆风…...
Cursor实现用excel数据填充word模版的方法
cursor主页:https://www.cursor.com/ 任务目标:把excel格式的数据里的单元格,按照某一个固定模版填充到word中 文章目录 注意事项逐步生成程序1. 确定格式2. 调试程序 注意事项 直接给一个excel文件和最终呈现的word文件的示例,…...

中南大学无人机智能体的全面评估!BEDI:用于评估无人机上具身智能体的综合性基准测试
作者:Mingning Guo, Mengwei Wu, Jiarun He, Shaoxian Li, Haifeng Li, Chao Tao单位:中南大学地球科学与信息物理学院论文标题:BEDI: A Comprehensive Benchmark for Evaluating Embodied Agents on UAVs论文链接:https://arxiv.…...
mongodb源码分析session执行handleRequest命令find过程
mongo/transport/service_state_machine.cpp已经分析startSession创建ASIOSession过程,并且验证connection是否超过限制ASIOSession和connection是循环接受客户端命令,把数据流转换成Message,状态转变流程是:State::Created 》 St…...

基于Flask实现的医疗保险欺诈识别监测模型
基于Flask实现的医疗保险欺诈识别监测模型 项目截图 项目简介 社会医疗保险是国家通过立法形式强制实施,由雇主和个人按一定比例缴纳保险费,建立社会医疗保险基金,支付雇员医疗费用的一种医疗保险制度, 它是促进社会文明和进步的…...

vscode(仍待补充)
写于2025 6.9 主包将加入vscode这个更权威的圈子 vscode的基本使用 侧边栏 vscode还能连接ssh? debug时使用的launch文件 1.task.json {"tasks": [{"type": "cppbuild","label": "C/C: gcc.exe 生成活动文件"…...

UDP(Echoserver)
网络命令 Ping 命令 检测网络是否连通 使用方法: ping -c 次数 网址ping -c 3 www.baidu.comnetstat 命令 netstat 是一个用来查看网络状态的重要工具. 语法:netstat [选项] 功能:查看网络状态 常用选项: n 拒绝显示别名&#…...
OkHttp 中实现断点续传 demo
在 OkHttp 中实现断点续传主要通过以下步骤完成,核心是利用 HTTP 协议的 Range 请求头指定下载范围: 实现原理 Range 请求头:向服务器请求文件的特定字节范围(如 Range: bytes1024-) 本地文件记录:保存已…...
鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个医院查看报告小程序
一、开发环境准备 工具安装: 下载安装DevEco Studio 4.0(支持HarmonyOS 5)配置HarmonyOS SDK 5.0确保Node.js版本≥14 项目初始化: ohpm init harmony/hospital-report-app 二、核心功能模块实现 1. 报告列表…...

ElasticSearch搜索引擎之倒排索引及其底层算法
文章目录 一、搜索引擎1、什么是搜索引擎?2、搜索引擎的分类3、常用的搜索引擎4、搜索引擎的特点二、倒排索引1、简介2、为什么倒排索引不用B+树1.创建时间长,文件大。2.其次,树深,IO次数可怕。3.索引可能会失效。4.精准度差。三. 倒排索引四、算法1、Term Index的算法2、 …...

涂鸦T5AI手搓语音、emoji、otto机器人从入门到实战
“🤖手搓TuyaAI语音指令 😍秒变表情包大师,让萌系Otto机器人🔥玩出智能新花样!开整!” 🤖 Otto机器人 → 直接点明主体 手搓TuyaAI语音 → 强调 自主编程/自定义 语音控制(TuyaAI…...