uniapp H5、小程序、APP端自定义不同运行情况(开发、测试、生产)、自定义 ...

种地  金牌会员 | 2024-7-21 02:44:08 | 显示全部楼层 | 阅读模式
打印 上一主题 下一主题

主题 554|帖子 554|积分 1662


前言

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

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

HBuildex默认编译平台比方有H5端、小程序端、APP端,像小程序端细分另有微信小程序,钉钉小程序等,不同编译平台我们可以用条件编译来指定特殊代码运行在哪种平台上。比方:
  1.          // #ifdef H5   
  2.             let        baseUrl = 'h5'         //H5端才执行
  3.                 // #endif       
  4.                 // #ifdef MP-WEIXIN
  5.              let        baseUrl ='weixin'                 //微信小程序端才执行
  6.                 // #endif
复制代码
而所有编译平台我们都可以在编辑器-运行菜单或者发现菜单下找到,自定义新的条件编译平台实在就是在编辑器发现/运行菜单新增一种编译类型,并和上面一样支持条件编译。

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

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

uni-app 通过在package.json文件中增加uni-app扩展节点,可实现自定义条件编译平台。
比方:
  1. "uni-app": {
  2.         "scripts": {
  3.             "h5-dev": {
  4.                 "title": "h5开发环境",
  5.                 "env": {
  6.                     "UNI_PLATFORM": "h5",
  7.                     "ENV_TYPE": "h5-dev"
  8.                 },
  9.                 "define": {
  10.                     "H5-DEV": true
  11.                 }
  12.             }
  13.             .....
复制代码
字段阐明:
  1. {
  2.     /**
  3.      * package.json其它原有配置
  4.      * 拷贝代码后请去掉注释!
  5.      */
  6.     "uni-app": {// 扩展配置
  7.         "scripts": {
  8.             "custom-platform": { //自定义编译平台配置,可通过cli方式调用
  9.                 "title":"自定义扩展名称", // 在HBuilderX中会显示在 运行/发行 菜单中
  10.                 "browser":"",  //运行到的目标浏览器,仅当UNI_PLATFORM为h5时有效
  11.                 "env": {//环境变量
  12.                     "UNI_PLATFORM": "",  //基准平台
  13.                     "MY_TEST": "", // ... 其他自定义环境变量
  14.                  },
  15.                 "define": { //自定义条件编译
  16.                     "CUSTOM-CONST": true //自定义条件编译常量,建议为大写
  17.                 }
  18.             }
  19.         }   
  20.     }
  21. }
复制代码
如果项目没有package.json文件可通过npm init初始化出来
留意阐明

  • UNI_PLATFORM只支持下列值:h5、mp-weixin、mp-alipay、mp-baidu、mp-toutiao、mp-qq,不支持app端,也即只支持小程序和H5自定义条件编译平台
  • package.json文件中不答应出现注释,否则扩展配置无效
   uniapp默认运行是开发情况,打包是生产情况,可通过 process.env.NODE_ENV 判断当前情况是开发情况还是生产情况。
  1. if (process.env.NODE_ENV === 'development') {
  2.         console.log('开发环境');
  3. } else {
  4.         console.log('生产环境');
  5. }
复制代码
  通过上面字段配置阐明可以看到env下我们可以自定义字段来标识该编译平台的情况变量 ,比方上面截图1那样,可以通过process.env.ENV_TYPE来获取情况值
  1. console.log(process.env.ENV_TYPE)//h5-dev
复制代码
通过自定义节点扩展可以在编辑器运行或者发现下拉菜单看到新增的编译平台(自定义情况)


更多package.json配置阐明点击查看
三、动态设置服务器哀求地址



  • 先定义各端情况变量文件env.js
  1. // h5开发环境
  2. const h5Dev = {
  3.         baseUrl: 'https://devh5.....'
  4. }
  5. // h5测试环境
  6. const h5Test= {
  7.         baseUrl: 'https://testh5.....'
  8. }
  9. // h5生产环境
  10. const h5Prod= {
  11.         baseUrl: 'https://prodh5.....'
  12. }
  13. // 微信小程序开发环境
  14. const mpWeixinDev = {
  15.         baseUrl: 'https://devwx.....'
  16. }
  17. // 微信小程序测试环境
  18. const mpWeixinTest= {
  19.         baseUrl: 'https://testwx.....'
  20. }
  21. // 微信小程序生产环境
  22. const mpWeixinProd= {
  23.         baseUrl: 'https://productionwx.....'
  24. }
  25. // app开发环境
  26. const appDev = {
  27.         baseUrl: 'https://devApp.....'
  28. }
  29. // app测试环境
  30. const appTest= {
  31.         baseUrl: 'https://testApp.....'
  32. }
  33. // app生产环境
  34. const appProd= {
  35.         baseUrl: 'https://productionApp.....'
  36. }
  37. const envConfig = {
  38.         'h5-dev':h5Dev,
  39.         'h5-test':h5Test,
  40.         'h5-prod':h5Prod,
  41.         'mp-weixin-dev':mpWeixinDev,
  42.         'mp-weixin-test':mpWeixinTest,
  43.         'mp-weixin-prod':mpWeixinProd,
  44.         'app-dev':appDev,
  45.         'app-test':appTest,
  46.         'app-prod':appProd,       
  47. }
  48. module.exports=envConfig
复制代码
此处定义的情况字段要跟package.json对应情况字段一致


  • package.json添加H5和小程序自定义情况
  1. {
  2.   {
  3.     "name": "",
  4.     "version": "1.0.1",
  5.     "description": "",
  6.     "main": "main.js",
  7.     "scripts": {
  8.         "test": "echo "Error: no test specified" && exit 1"
  9.     },
  10.     "author": "",
  11.     "license": "ISC",
  12.     "uni-app": {
  13.         "scripts": {
  14.             "h5-dev": {
  15.                 "title": "h5开发环境",
  16.                 "env": {
  17.                     "UNI_PLATFORM": "h5",
  18.                     "ENV_TYPE": "h5-dev"
  19.                 },
  20.                 "define": {
  21.                     "H5-DEV": true
  22.                 }
  23.             },
  24.             "h5-test": {
  25.                 "title": "h5测试环境",
  26.                 "env": {
  27.                     "UNI_PLATFORM": "h5",
  28.                     "ENV_TYPE": "h5-test"
  29.                 },
  30.                 "define": {
  31.                     "H5-TEST": true
  32.                 }
  33.             },
  34.             "h5-prod": {
  35.                 "title": "h5生产环境",
  36.                 "env": {
  37.                     "UNI_PLATFORM": "h5",
  38.                     "H5_NODE_ENV": "h5-prod"
  39.                 },
  40.                 "define": {
  41.                     "H5-PROD": true
  42.                 }
  43.             },
  44.             "mp-weixin-dev": {
  45.                 "title": "小程序开发环境",
  46.                 "env": {
  47.                     "UNI_PLATFORM": "mp-weixin",
  48.                     "ENV_TYPE": "mp-weixin-dev"
  49.                 },
  50.                 "define": {
  51.                     "MP-WEIXIN-DEV": true
  52.                 }
  53.             },
  54.             "mp-weixin-test": {
  55.                 "title": "小程序测试环境",
  56.                 "env": {
  57.                     "UNI_PLATFORM": "mp-weixin",
  58.                     "ENV_TYPE": "mp-weixin-test"
  59.                 },
  60.                 "define": {
  61.                     "MP-WEIXIN-TEST": true
  62.                 }
  63.             },
  64.             "mp-weixin-prod": {
  65.                 "title": "小程序生产环境",
  66.                 "env": {
  67.                     "UNI_PLATFORM": "mp-weixin",
  68.                     "ENV_TYPE": "mp-weixin-prod"
  69.                 },
  70.                 "define": {
  71.                     "MP-WEIXIN-PROD": true
  72.                 }
  73.             }
  74.         }
  75.     },
  76.   }
  77. }
复制代码
此处ENV_TYPE定义值最好和编译平台名称字段一致


  • request.js接口哀求动态获取baseUrl
  1. import envConfig from './env.js'
  2. //服务器请求地址
  3. const baseUrl = envConfig[process.env.ENV_TYPE].baseUrl
复制代码
至此小程序端和H5好像没啥问题了,但是APP端不支持自定编译平台,所以只能手动切换
  1. import envConfig from './env.js'
  2. const appEnv="app-dev";//定义一个变量控制APP端环境
  3. // #ifndef APP
  4. const baseUrl = envConfig[process.env.ENV_TYPE].baseUrl
  5. // #endif
  6. // #ifdef APP
  7. const baseUrl = envConfig[appEnv].baseUrl
  8. // #endif
复制代码
从上面代码看我们定义了一个appEnv变量来手动控制APP打包或运行情况,只需每次手动切换即可。
到此三端配置是不是竣事了?仔细想想——H5端有个大问题,我们知道H5端有跨域问题一般不能直接访问baseUrl,在vue2开发时候通例做法是通过manifest.json下配置代理解决跨域问题。
比方:
manifest.json
  1. "h5" : {
  2.         "devServer" : {
  3.             "disableHostCheck" : true,
  4.             //配置代理
  5.             "proxy" : {
  6.                 "/api" : {
  7.                     "target" : "https://devh5.....",//h5开发环境
  8.                     "changeOrigin" : true,
  9.                     "secure" : false,
  10.                     "ws" : true
  11.                 }
  12.             }
  13.         }
  14.     },
复制代码
显然问题转化为根据不同编译情况动态修改target值,比如运行h5测试情况,target值就要变成env.js定义的h5Test.baseUrl
四、动态修改manifest.json

阐明:manifest.json下是无法读取process.env.ENV_TYPE值,我们只能通过node文件流写入方式去修改target值
具体如下:
1.根目次新增文件 modifyManifest.js

写入:
  1. const fs = require('fs')
  2. //自定义的环境变量根据实际对应路径引入
  3. const envConfig=require('./config/env.js')
  4. //读取manifest.json内容
  5. fs.readFile(`${__dirname}/manifest.json`, (error, res)=> {
  6.         if (!error) {
  7.                 let data = JSON.parse(res.toString());
  8.                 //此时process.env.ENV_TYPE依然无法读取到但是可以读取process.env.UNI_SCRIPT,该值为自定义编译平台配置字段名称,这就是上面取字段时候要求和自定义编译平台字段一样原因
  9.                 let env =process.env.UNI_SCRIPT
  10.                 if (env&&env.includes('h5')) {
  11.                         if ( data?.h5?.devServer?.proxy) {
  12.                                 let proxy= data.h5.devServer.proxy
  13.                                 for (let key in proxy) {
  14.                                         proxy[key].target =envConfig[env].baseUrl
  15.                                 }
  16.                                 // console.log(JSON.stringify(data.h5),'proxy')
  17.                            //重新写入修改后内容
  18.                                 fs.writeFile(
  19.                                       `${__dirname}/manifest.json`,
  20.                                       JSON.stringify(data),
  21.                                       {
  22.                                         encoding: 'utf-8'
  23.                                       },
  24.                                        (error)=>{
  25.                                         if (error) {
  26.                                           console.log(error,'修改失败')
  27.                                         } else {
  28.                                           console.log('修改成功')
  29.                                         }
  30.                                       }
  31.                                     )
  32.                                
  33.                         }
  34.                 }
  35.         }
  36. })
复制代码
2.vue.config.js引入modifyManifest.js

vue.config.js(没有该文件新建,位于项目根目次)新增:
  1. require('./modifyManifest.js')
复制代码
留意:兼容性写法此处用require非import
至此,每次通过运行-编译不同的情况,编辑器会动态修改manifest.json-target值,代理指向对应的情况
vue3 H5端动态修改代理

   vue3 uniapp构建工具换成vite,跨域代理方式也不同,上述方法就不能通用
  回顾下uniapp vite配置代理方式
根目次下新建vite.config.js,写入
  1. import { defineConfig } from 'vite'
  2. import uni from '@dcloudio/vite-plugin-uni'
  3. export default defineConfig({
  4.         plugins: [
  5.                 uni()
  6.         ],
  7.         server: {
  8.                 port: 3000,
  9.                 proxy: {
  10.                         '/api': {
  11.                                 target:"https://h5Test....",
  12.                                 changeOrigin: true,
  13.                        
  14.                         }
  15.                 }
  16.         }
  17. })
复制代码
我们只要动态修改target值就行了,vite.config.js支持导入外部文件,当前我们自定义的情况可以通过
process.env.UNI_SCRIPT获取
完整代码如下
env.js
  1. // h5开发环境
  2. const h5Dev = {
  3.         baseUrl: 'http://h5Dev...'
  4. }
  5. // h5测试环境
  6. const h5Test = {
  7.         baseUrl: 'https://h5Test...'
  8. }
  9. // h5生产环境
  10. const h5Prod = {
  11.         baseUrl: 'https://h5Prod...'
  12. }
  13. // 微信小程序开发环境
  14. const mpWeixinDev = {
  15.         baseUrl: 'https://devwx.....'
  16. }
  17. // 微信小程序测试环境
  18. const mpWeixinTest = {
  19.         baseUrl: 'https://testwx.....'
  20. }
  21. // 微信小程序生产环境
  22. const mpWeixinProd = {
  23.         baseUrl: 'https://productionwx.....'
  24. }
  25. // app开发环境
  26. const appDev = {
  27.         baseUrl: 'https://devApp.....'
  28. }
  29. // app测试环境
  30. const appTest = {
  31.         baseUrl: 'https://testApp.....'
  32. }
  33. // app生产环境
  34. const appProd = {
  35.         baseUrl: 'https://productionApp.....'
  36. }
  37. //获取当前H5环境
  38. const getH5Env = () => {
  39.         let currentEnv = process.env.UNI_SCRIPT //当前定义的环境
  40.         //环境枚举值
  41.         let envList = [{
  42.                 envTag: 'h5-dev',
  43.                 value: h5Dev.baseUrl
  44.         }, {
  45.                 envTag: 'h5-test',
  46.                 value: h5Test.baseUrl
  47.         }, {
  48.                 envTag: 'h5-prod',
  49.                 value: h5Prod.baseUrl
  50.         }]
  51.         return (envList.find(item => item.envTag == currentEnv)||{}).value||''
  52. }
  53. const envConfig = {
  54.         'h5-dev': h5Dev,
  55.         'h5-test': h5Test,
  56.         'h5-prod': h5Prod,
  57.         'mp-weixin-dev': mpWeixinDev,
  58.         'mp-weixin-test': mpWeixinTest,
  59.         'mp-weixin-prod': mpWeixinProd,
  60.         'app-dev': appDev,
  61.         'app-test': appTest,
  62.         'app-prod': appProd,
  63.         getH5Env
  64. }
  65. module.exports = envConfig
复制代码
  env.js新增一个getH5Env方法获取当前定义情况值
  vite.config.js
  1. import { defineConfig } from 'vite'
  2. import uni from '@dcloudio/vite-plugin-uni'
  3. import envConfig from './env.js'
  4. export default defineConfig({
  5.         plugins: [
  6.                 uni()
  7.         ],
  8.         server: {
  9.                 port: 3000,
  10.                 proxy: {
  11.                         '/api': {
  12.                                 target:envConfig.getH5Env(),
  13.                                 changeOrigin: true,
  14.                        
  15.                         }
  16.                 }
  17.         }
  18. })
复制代码
总结

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

传送门:点击查看

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

种地

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表