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

2024-06-04 5320阅读

文章目录

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

        前言

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


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

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

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

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

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

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


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

        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
        

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

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

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

        更多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,在vue2开发时候常规做法是通过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_SCRIPT
              		if (env&&env.includes('h5')) {
              			if ( data?.h5?.devServer?.proxy) {
              				let proxy= data.h5.devServer.proxy
              				for (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值,代理指向对应的环境

              vue3 H5端动态修改代理

              vue3 uniapp构建工具换成vite,跨域代理方式也不同,上述方法就不能通用

              回顾下uniapp vite配置代理方式

              根目录下新建vite.config.js,写入

              import { defineConfig } from 'vite'
              import uni from '@dcloudio/vite-plugin-uni'
              export default defineConfig({
              	plugins: [
              		uni()
              	],
              	server: {
              		port: 3000,
              		proxy: {
              			'/api': {
              				target:"https://h5Test....",
              				changeOrigin: true,
              			
              			}
              		}
              	}
              })
              

              我们只要动态修改target值就行了,vite.config.js支持导入外部文件,当前我们自定义的环境可以通过

              process.env.UNI_SCRIPT获取

              完整代码如下

              env.js

              // h5开发环境
              const h5Dev = {
              	baseUrl: 'http://h5Dev...'
              }
              // h5测试环境
              const h5Test = {
              	baseUrl: 'https://h5Test...'
              }
              // h5生产环境
              const h5Prod = {
              	baseUrl: 'https://h5Prod...'
              }
              // 微信小程序开发环境
              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.....'
              }
              //获取当前H5环境
               const getH5Env = () => {
              	let currentEnv = process.env.UNI_SCRIPT //当前定义的环境
              	//环境枚举值
              	let envList = [{
              		envTag: 'h5-dev',
              		value: h5Dev.baseUrl
              	}, {
              		envTag: 'h5-test',
              		value: h5Test.baseUrl
              	}, {
              		envTag: 'h5-prod',
              		value: h5Prod.baseUrl
              	}]
              	return (envList.find(item => item.envTag == currentEnv)||{}).value||''
              }
              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,
              	getH5Env
              }
              
              module.exports = envConfig
              

              env.js新增一个getH5Env方法获取当前定义环境值

              vite.config.js

              import { defineConfig } from 'vite'
              import uni from '@dcloudio/vite-plugin-uni'
              import envConfig from './env.js'
              export default defineConfig({
              	plugins: [
              		uni()
              	],
              	server: {
              		port: 3000,
              		proxy: {
              			'/api': {
              				target:envConfig.getH5Env(),
              				changeOrigin: true,
              			
              			}
              		}
              	}
              })
              

              总结

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

              示例代码

              传送门:点击查看


    免责声明:我们致力于保护作者版权,注重分享,被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理! 图片声明:本站部分配图来自人工智能系统AI生成,觅知网授权图片,PxHere摄影无版权图库和百度,360,搜狗等多加搜索引擎自动关键词搜索配图,如有侵权的图片,请第一时间联系我们,邮箱:ciyunidc@ciyunshuju.com。本站只作为美观性配图使用,无任何非法侵犯第三方意图,一切解释权归图片著作权方,本站不承担任何责任。如有恶意碰瓷者,必当奉陪到底严惩不贷!

    目录[+]