当前位置: 首页 > news >正文

uniapp H5、小程序、APP端自定义不同运行环境(开发、测试、生产)、自定义条件编译平台、以及动态修改manifest.json值讲解

文章目录

  • 前言
  • 一、自定义条件编译平台是什么?
  • 二、新增自定义条件编译平台
  • 三、动态设置服务器请求地址
    • 四、动态修改manifest.json
      • 1.根目录新增文件 modifyManifest.js
      • 2.vue.config.js引入modifyManifest.js
    • 总结
    • 示例代码


前言

企业项目开发流程上一般都要配置多个运行环境(不同的服务器请求地址)。不同环境有不同用途,主要用于区分开发、测试、上线,对应的环境称为开发环境、测试环境、生产环境。实际开发中经常要在不同环境进行联调或者打包,对于uniapp每次都要手动修改服务请求地址很是麻烦,有什么方法能实现按需运行按需打包呢,答案是——自定义条件编译平台


一、自定义条件编译平台是什么?

HBuildex默认编译平台例如有H5端、小程序端、APP端,像小程序端细分还有微信小程序,钉钉小程序等,不同编译平台我们可以用条件编译来指定特殊代码运行在哪种平台上。例如:

         // #ifdef H5   let	baseUrl = 'h5'         //H5端才执行// #endif	// #ifdef MP-WEIXINlet	baseUrl ='weixin' 		//微信小程序端才执行// #endif

而所有编译平台我们都可以在编辑器-运行菜单或者发现菜单下找到,自定义新的条件编译平台其实就是在编辑器发现/运行菜单新增一种编译类型,并和上面一样支持条件编译。
在这里插入图片描述

更多的条件编译官方文档说明可以点击查看


二、新增自定义条件编译平台

uni-app 通过在package.json文件中增加uni-app扩展节点,可实现自定义条件编译平台。
例如:

"uni-app": {"scripts": {"h5-dev": {"title": "h5开发环境","env": {"UNI_PLATFORM": "h5","ENV_TYPE": "h5-dev"},"define": {"H5-DEV": true}}.....

字段说明:

{/*** package.json其它原有配置 * 拷贝代码后请去掉注释!*/"uni-app": {// 扩展配置"scripts": {"custom-platform": { //自定义编译平台配置,可通过cli方式调用"title":"自定义扩展名称", // 在HBuilderX中会显示在 运行/发行 菜单中"browser":"",  //运行到的目标浏览器,仅当UNI_PLATFORM为h5时有效"env": {//环境变量"UNI_PLATFORM": "",  //基准平台"MY_TEST": "", // ... 其他自定义环境变量},"define": { //自定义条件编译"CUSTOM-CONST": true //自定义条件编译常量,建议为大写}}}    }
}

如果项目没有package.json文件可通过npm init初始化出来

注意说明

  1. UNI_PLATFORM只支持下列值:h5、mp-weixin、mp-alipay、mp-baidu、mp-toutiao、mp-qq,不支持app端,也即只支持小程序和H5自定义条件编译平台
  2. package.json文件中不允许出现注释,否则扩展配置无效

uniapp默认运行是开发环境,打包是生产环境,可通过 process.env.NODE_ENV 判断当前环境是开发环境还是生产环境。

if (process.env.NODE_ENV === 'development') {console.log('开发环境');
} else {console.log('生产环境');
}

通过上面字段配置说明可以看到env下我们可以自定义字段来标识该编译平台的环境变量 ,例如上面截图1那样,可以通过process.env.ENV_TYPE来获取环境值

console.log(process.env.ENV_TYPE)//h5-dev

通过自定义节点扩展可以在编辑器运行或者发现下拉菜单看到新增的编译平台(自定义环境)

在这里插入图片描述

更多package.json配置说明点击查看

三、动态设置服务器请求地址

  • 先定义各端环境变量文件env.js
// h5开发环境
const h5Dev = {baseUrl: 'https://devh5.....'
}// h5测试环境
const h5Test= {baseUrl: 'https://testh5.....'}// h5生产环境
const h5Prod= {baseUrl: 'https://prodh5.....'}// 微信小程序开发环境
const mpWeixinDev = {baseUrl: 'https://devwx.....'
}// 微信小程序测试环境
const mpWeixinTest= {baseUrl: 'https://testwx.....'}// 微信小程序生产环境
const mpWeixinProd= {baseUrl: 'https://productionwx.....'}
// app开发环境
const appDev = {baseUrl: 'https://devApp.....'
}// app测试环境
const appTest= {baseUrl: 'https://testApp.....'}// app生产环境
const appProd= {baseUrl: 'https://productionApp.....'}const envConfig = {'h5-dev':h5Dev,'h5-test':h5Test,'h5-prod':h5Prod,'mp-weixin-dev':mpWeixinDev,'mp-weixin-test':mpWeixinTest,'mp-weixin-prod':mpWeixinProd,'app-dev':appDev,'app-test':appTest,'app-prod':appProd,	
}
module.exports=envConfig

此处定义的环境字段要跟package.json对应环境字段一致

  • package.json添加H5和小程序自定义环境
{{"name": "","version": "1.0.1","description": "","main": "main.js","scripts": {"test": "echo \"Error: no test specified\" && exit 1"},"author": "","license": "ISC","uni-app": {"scripts": {"h5-dev": {"title": "h5开发环境","env": {"UNI_PLATFORM": "h5","ENV_TYPE": "h5-dev"},"define": {"H5-DEV": true}},"h5-test": {"title": "h5测试环境","env": {"UNI_PLATFORM": "h5","ENV_TYPE": "h5-test"},"define": {"H5-TEST": true}},"h5-prod": {"title": "h5生产环境","env": {"UNI_PLATFORM": "h5","H5_NODE_ENV": "h5-prod"},"define": {"H5-PROD": true}},"mp-weixin-dev": {"title": "小程序开发环境","env": {"UNI_PLATFORM": "mp-weixin","ENV_TYPE": "mp-weixin-dev"},"define": {"MP-WEIXIN-DEV": true}},"mp-weixin-test": {"title": "小程序测试环境","env": {"UNI_PLATFORM": "mp-weixin","ENV_TYPE": "mp-weixin-test"},"define": {"MP-WEIXIN-TEST": true}},"mp-weixin-prod": {"title": "小程序生产环境","env": {"UNI_PLATFORM": "mp-weixin","ENV_TYPE": "mp-weixin-prod"},"define": {"MP-WEIXIN-PROD": true}}}},}
}

此处ENV_TYPE定义值最好和编译平台名称字段一致

  • request.js接口请求动态获取baseUrl
import envConfig from './env.js'
//服务器请求地址
const baseUrl = envConfig[process.env.ENV_TYPE].baseUrl

至此小程序端和H5好像没啥问题了,但是APP端不支持自定编译平台,所以只能手动切换

import envConfig from './env.js'
const appEnv="app-dev";//定义一个变量控制APP端环境
// #ifndef APP
const baseUrl = envConfig[process.env.ENV_TYPE].baseUrl
// #endif
// #ifdef APP
const baseUrl = envConfig[appEnv].baseUrl
// #endif

从上面代码看我们定义了一个appEnv变量来手动控制APP打包或运行环境,只需每次手动切换即可。

到此三端配置是不是结束了?仔细想想——H5端有个大问题,我们知道H5端有跨域问题一般不能直接访问baseUrl,在开发时候常规做法是通过manifest.json下配置代理解决跨域问题。
例如:

manifest.json

"h5" : {"devServer" : {"disableHostCheck" : true,//配置代理"proxy" : {"/api" : {"target" : "https://devh5.....",//h5开发环境"changeOrigin" : true,"secure" : false,"ws" : true}}}},

显然问题转化为根据不同编译环境动态修改target值,比如运行h5测试环境,target值就要变成env.js定义的h5Test.baseUrl

四、动态修改manifest.json

说明:manifest.json下是无法读取process.env.ENV_TYPE值,我们只能通过node文件流写入方式去修改target值

具体如下:

1.根目录新增文件 modifyManifest.js

写入:

const fs = require('fs')
//自定义的环境变量根据实际对应路径引入
const envConfig=require('./config/env.js')
//读取manifest.json内容
fs.readFile(`${__dirname}/manifest.json`, (error, res)=> {if (!error) {let data = JSON.parse(res.toString());//此时process.env.ENV_TYPE依然无法读取到但是可以读取process.env.UNI_SCRIPT,该值为自定义编译平台配置字段名称,这就是上面取字段时候要求和自定义编译平台字段一样原因let env =process.env.UNI_SCRIPTif (env&&env.includes('h5')) {if ( data?.h5?.devServer?.proxy) {let proxy= data.h5.devServer.proxyfor (let key in proxy) {proxy[key].target =envConfig[env].baseUrl}// console.log(JSON.stringify(data.h5),'proxy')//重新写入修改后内容fs.writeFile(`${__dirname}/manifest.json`,JSON.stringify(data),{encoding: 'utf-8'},(error)=>{if (error) {console.log(error,'修改失败')} else {console.log('修改成功')}})}}}
})

2.vue.config.js引入modifyManifest.js

vue.config.js(没有该文件新建,位于项目根目录)新增:

require('./modifyManifest.js')

注意:兼容性写法此处用require非import

至此,每次通过运行-编译不同的环境,编辑器会动态修改manifest.json-target值,代理指向对应的环境

总结

通过上面介绍我们实现了自定义编译平台、自定义环境运行和打包,了解了如何动态修改manifest.json内部值,也可以根据实际场景需求扩展比如动态修改小程序appid值、不同自定义环境运行不同逻辑代码等扩展。

示例代码

传送门:点击查看

相关文章:

  • ubuntu编译sqlite3并使用
  • 关于用css设置input输入框hover的时候的样式以及当input为disabled的时候,不要让hover样式生效
  • Python——常见内置模块
  • 【Linux】第二十站:模拟实现shell
  • 《向量数据库指南》——向量数据库Milvus Cloud搭建Excel公式编辑器助手
  • 如何打造“面向体验”的音视频能力——对话火山引擎王悦
  • vivado产生报告阅读分析24-读取和解释时序路径特性报告
  • MyBatis-Plus简介和入门操作
  • 哈希思想的应用
  • JAVA编程规范-集合、并发(阿里手册)
  • RabbitMQ 搭建和工作模式
  • <HarmonyOS第一课>1·运行Hello World【课后考核】
  • C++中声明共用体
  • MySQL执行计划分析
  • 【机器学习】聚类(二):原型聚类:LVQ聚类(学习向量量化)
  • @jsonView过滤属性
  • IndexedDB
  • OSS Web直传 (文件图片)
  • Spring Cloud(3) - 服务治理: Spring Cloud Eureka
  • SpringCloud集成分布式事务LCN (一)
  • 代理模式
  • 缓存与缓冲
  • 深入 Nginx 之配置篇
  • 手写一个CommonJS打包工具(一)
  • 通过来模仿稀土掘金个人页面的布局来学习使用CoordinatorLayout
  • 由插件封装引出的一丢丢思考
  • ​油烟净化器电源安全,保障健康餐饮生活
  • !!Dom4j 学习笔记
  • # 深度解析 Socket 与 WebSocket:原理、区别与应用
  • (5)STL算法之复制
  • (pytorch进阶之路)CLIP模型 实现图像多模态检索任务
  • (附源码)ssm高校志愿者服务系统 毕业设计 011648
  • (九)信息融合方式简介
  • (力扣题库)跳跃游戏II(c++)
  • (一)VirtualBox安装增强功能
  • (转)甲方乙方——赵民谈找工作
  • .L0CK3D来袭:如何保护您的数据免受致命攻击
  • .MSSQLSERVER 导入导出 命令集--堪称经典,值得借鉴!
  • .net core使用ef 6
  • .Net MVC4 上传大文件,并保存表单
  • .Net调用Java编写的WebServices返回值为Null的解决方法(SoapUI工具测试有返回值)
  • .vue文件怎么使用_我在项目中是这样配置Vue的
  • ??在JSP中,java和JavaScript如何交互?
  • [20150629]简单的加密连接.txt
  • [20171102]视图v$session中process字段含义
  • [2544]最短路 (两种算法)(HDU)
  • [④ADRV902x]: Digital Filter Configuration(发射端)
  • [Android Pro] android 混淆文件project.properties和proguard-project.txt
  • [Bzoj4722]由乃(线段树好题)(倍增处理模数小快速幂)
  • [ESP32 IDF]web server
  • [Fri 26 Jun 2015 ~ Thu 2 Jul 2015] Deep Learning in arxiv
  • [Godot] 3D拾取
  • [Hive] INSERT OVERWRITE DIRECTORY要注意的问题
  • [iOS]如何删除工程里面用cocoapods导入的第三方库
  • [JS]数据类型