uni-app的多环境配置不同的BASE_URL

uni-app的APP环境和H5环境,怎么实现在不同环境下使用不同的配置? 类似 env.dev env.prod 多环境功能如何实现?

uni-app如何实现 process.env.NODE_ENV 根据运行环境自定义环境变量?


前言

  • 【我开发的操作系统是 MacOS,若你的是 Windows 系统,里面涉及到指令的地方,我会尽量写上针对windows系统的官方文档链接】
  • 我在一个uniapp实际项目代码中看到访问api地址的变量是前端写死的,每次发不同环境的包时,都要去修改这些变量
  • 所以我就在好奇心的驱使下,探索了一下uniapp在多环境方面解决方案
  • 先说下结论:uniapp在多环境方面解决方案非常尴尬😅,说它有吧,有那么点,但略显尴尬,跟没有一样😓!我通过挖掘官方资料,最终终于想到了个人感觉相对合理一点的方案
  • 【接下来请看我整理出来的在 APP和H5 两种平台下的多环境处理方案,至于小程序之类的其他杂牌,也大同小异,若有啥不对,欢迎友好评论,感谢🙏】

方案整体说明

  • uniapp在多环境方面的解决方案,仍然需要针对不同的平台,即 APP平台和H5平台的解决方案是不同的
  • uni-app 的 process.env.NODE_ENV 是无法修改的,官方说明是开发运行时为 'development',打包构建运行时为 'production' ,所以直接放弃使用 process.env.NODE_ENV 吧,我各种尝试下来,觉得uniapp里的process.env.NODE_ENV在实际开发中几乎就是多余的(因为对于H5环境,官方提供的自定义扩展发包配置可以直接新增编译变量控制代码块,也就无需NODE_ENV了)

方案代码展示!!

第一步 -[APP环境]-【创建好APP环境通过指令打包需要用到的配置文件】
  • 这些配置文件是用于通过 Hbuildx cli 来实现在终端中使用指令打包APP,因为若通过点击Hbuildx的菜单上发包按钮打包的话,每次都要输入不同的appid、证书和密码,太麻烦了,预制好这些文件,直接通过命令行操作就方便多了

  • 【uniapp的cli分为两种(若想直接通过npm调用cli,就必须是通过vue+hbuilder cli创建的项目才行,而我遇到的项目是直接通过Builderx创建的,所以只能使用hbuilderx cli来执行命令)】:官方文档链接

  • 如 configure-dev.json

  • uniapp hbuildx cli 配置文件 官方说明文档

json 复制代码
{
    "project": "eManufacture-app",
    "platform":"ios,android",
    "iscustom": false,
    "safemode": false,
    "android": {
      "packagename":"com.abc.devxxxapp",
      "androidpacktype":"0",
      "certalias":"__UNI__A5B5E58",
      "certfile":"/Users/abc/Documents/my-app/pub-package/androidfiles/certfile.keystore",
      "certpassword":"adr111"
      },
    "ios": {
       "bundle":"com.ab-c.dev-xxx-app",
       "supporteddevice":"iPhone,iPad",
       "profile":"/Users/abc/Documents/my-app/pub-package/iosfiles/ios.mobileprovision",
       "certfile":"/Users/abc/Documents/my-app/pub-package/iosfiles/ios.p12",
       "certpassword":"abc222"
    },
    "isconfusion":false,
    "splashads":false,
    "rpads":false,
    "pushads":false,
    "exchange":false
}
第二步【把发包命令和配置预制在package.json脚本中】
  • 同时也为 H5 环境加上针对多环境的自定义扩展uniapp发包脚本配置(即 package.json 中的 "uni-app":{"scripts": {...}} 这部分)
    • 可能你会想到为啥不给 APP 环境也配置自定义扩展发包配置呢?答:uniapp不支持(官方原话是"目前仅限如下枚举值:h5mp-weixinmp-alipaymp-baidump-toutiaomp-qq`")
  • 自定义扩展uniapp发包脚本配置 官方说明文档
  • 自定义扩展发包配置配置完成后,就能在【HbuildX菜单栏>发行>自定义发行】中使用了
  • package.json
json 复制代码
{
  "scripts":{
    "build-dev:app": "/Applications/HBuilderX.app/Contents/MacOS/cli pack --config /Users/abc/Documents/my-app/pub-package/configure-dev.json",
    "build-dev:android": "/Applications/HBuilderX.app/Contents/MacOS/cli pack --config /Users/abc/Documents/my-app/pub-package/configure-dev-android.json",
    "build-dev:ios": "/Applications/HBuilderX.app/Contents/MacOS/cli pack --config /Users/abc/Documents/my-app/pub-package/configure-dev-ios.json",
    "build-stage:app": "/Applications/HBuilderX.app/Contents/MacOS/cli pack --config /Users/abc/Documents/my-app/pub-package/configure-stage.json",
    "build-stage:android": "/Applications/HBuilderX.app/Contents/MacOS/cli pack --config /Users/abc/Documents/my-app/pub-package/configure-stage-android.json",
    "build-stage:ios": "/Applications/HBuilderX.app/Contents/MacOS/cli pack --config /Users/abc/Documents/my-app/pub-package/configure-stage-ios.json",
    "build-prod:app": "/Applications/HBuilderX.app/Contents/MacOS/cli pack --config /Users/abc/Documents/my-app/pub-package/configure-prod.json",
    "build-prod:android": "/Applications/HBuilderX.app/Contents/MacOS/cli pack --config /Users/abc/Documents/my-app/pub-package/configure-prod-android.json",
    "build-prod:ios": "/Applications/HBuilderX.app/Contents/MacOS/cli pack --config /Users/abc/Documents/my-app/pub-package/configure-prod-ios.json"
  },
  "uni-app": {
    "scripts": {
      "h5-dev": {
        "title": "H5-APP-测试环境", 
        "BROWSER": "chrome",
        "env": {
          "UNI_PLATFORM": "h5"
        },
        "define": { 
          "H5-DEV": true
        }
      },
      "h5-stage": {
        "title": "H5-APP-测试环境", 
        "BROWSER": "chrome",
        "env": {
          "UNI_PLATFORM": "h5"
        },
        "define": { 
          "H5-STAGE": true
        }
      },
      "h5-prod": {
        "title": "H5-APP-正式环境", 
        "BROWSER": "chrome",
        "env": {
          "UNI_PLATFORM": "h5"
        },
        "define": { 
          "H5-PROD": true
        }
      }
    }
  },
}
第三步【代码中编写config脚本文件】
  • 我项目中是把这些config文件放在了 /common/ 目录下使用的

  • 你根据自己项目情况,把config脚本文件到到相应的目录下使用即可

  • env-dev.js

arduino 复制代码
// dev 环境

export const BASE_URL_H5 = '/devapi'
export const BASE_URL_APP = 'https://aaa:8887/api'
  • env-stage.js
js 复制代码
// stage 环境

export const BASE_URL_H5 = '/stageapi'
export const BASE_URL_APP = 'https://aaa:8888/api'
  • env-prod.js
arduino 复制代码
// prod 环境

export const BASE_URL_H5 = '/prodapi'
export const BASE_URL_APP = 'https://aaa:8889/api'
  • config.js
js 复制代码
// ----------- APP 环境 --------------

// #ifdef APP-PLUS
// 通过创建多个 appid 实现区分多环境,其中 appid 是数组原因是:android 和 ios 的 appid 不同
const APPID_ENVS = {
    APPID_DEV: ['com.abc.devxxxapp','com.ab-c.dev-xxx-app'], // 对应 dev 环境的 appid
    APPID_STAGE: ['com.abc.stagexxxapp','com.ab-c.stage-xxx-app'], // 对应 stage 环境的 appid
    APPID_PROD: ['com.abc.prodxxxapp','com.ab-c.prod-xxx-app'], // 对应 prod 环境的 appid
}
import { BASE_URL_APP as BASE_URL_APP_DEV } from './env-dev.js'
import { BASE_URL_APP as BASE_URL_APP_STAGE } from './env-stage.js'
import { BASE_URL_APP as BASE_URL_APP_PROD } from './env-prod.js'

// 【*】暴露函数
export const getAppConfig = () => {
    let BASE_URL = ''
    const { appid } = plus.runtime
    if(APPID_ENVS.APPID_DEV.includes(appid)) {
        BASE_URL = BASE_URL_APP_DEV
    } else if(APPID_ENVS.APPID_STAGE.includes(appid)) {
        BASE_URL = BASE_URL_APP_STAGE
    } else if(APPID_ENVS.APPID_PROD.includes(appid)) {
        BASE_URL = BASE_URL_APP_PROD
    }
    return {
        BASE_URL
    }
}

// #endif

// ----------- H5 环境 -> 以下这些编译变量都是自定义扩展的(在【HbuildX菜单栏>发行>自定义发行】中使用) --------------

// #ifdef H5-DEV
import { BASE_URL_H5 } from './env-dev.js'
const BASE_URL = BASE_URL_H5
// #endif

// #ifdef H5-STAGE
import { BASE_URL_H5 } from './env-stage.js'
const BASE_URL = BASE_URL_H5
// #endif

// #ifdef H5-PROD
import { BASE_URL_H5 } from './env-prod.js'
const BASE_URL = BASE_URL_H5
// #endif

// #ifdef H5
// 【*】暴露函数
export const getAppConfig = () => {
    return {
        BASE_URL
    }
}
// #endif
  • 【以上3步其实就是多环境配置的核心方案了,接下来的步骤,主要是针对前端访问接口的 BASE_URL 控制了 】
*额外步骤* 第三步 -[针对H5环境]-【nginx代理配置】
  • 上面我们在 H5 环境代码块中,配置的 BASE_URL 是 /devapi 这样的,这是为了可以把实际访问接口的控制权放到服务端,这样可以避免当需要更改接口地址时,就不需要前端重写打包了,若接口地址写死在前端代码中,那一旦需要修改接口地址,就又要重写打包,重新部署,这就没必要了

  • 对于 APP 来说,我这边给到的方案是,也在服务端配置不同的 nginx 反向代理来转到实际的接口地址中,目的同上,对于APP来说重新打包就意味着要用户更新,而对于这种接口地址修改的问题,更要避免让用户去更新(所以我在不同的环境配置中写了不同的接口地址 BASE_URL_APP = 'https://aaa:8887/api BASE_URL_APP = 'https://aaa:8889/api BASE_URL_APP = 'https://aaa:8887/api

  • [针对H5]nginx.conf 案例代码(这份配置需要根据你项目情况来定了,这里写的仅供参考)

bash 复制代码
server {
    listen 80;
    server_name localhost;

    location /devapi/ {
        rewrite /devapi/(.*) /$1 break;
        proxy_pass https://abcsys.com:7777;
        proxy_set_header Host $host;
        proxy_method $request_method;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }

    location / {
        root   /usr/share/nginx/html;
        index  index.html index.htm;
        try_files $uri $uri/ /index.html;

        if ($request_uri ~ ^/api/) { 
            break;
        }
    }
}
  • [针对APP]nginx.conf 案例代码(这份配置需要根据你项目情况来定了,这里写的仅供参考)
ini 复制代码
server {
    listen 8887;
    server_name localhost;

    location /api/ {
        proxy_pass https://abcsys.com:7777;
        proxy_set_header Host $host;
        proxy_method $request_method;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}
*额外步骤* 第四步 -[H5部署]-【dockerfile参考】
  • dockerfile
dockerfile 复制代码
FROM nginx

# 拷贝web应用目录到容器目录
COPY /unpackage/dist/build/h5 /usr/share/nginx/html

# 拷贝自定义配置文件
COPY nginx.conf /etc/nginx/conf.d/default.conf

# 暴露端口
EXPOSE 80

CMD ["nginx", "-g", "daemon off;"]

# 创建镜像和容器指令
# docker build -t my-nginx:v1 .
# docker run -d --name my_nginx_container -p 8180:80 my-nginx:v1
  • 这里用到的 nginx.conf 内容如下:
nginx.conf 复制代码
server {
    listen 80;
    server_name localhost;

    location /devapi/ {
        # 重写前端代码中访问接口url /devapi/aaa/bbb 中的 /devapi/ 这部分,变为 /aaa/bbb
        # 和下面这句 proxy_pass https://abcsys.com:7777 组合效果最终就会把 /devapi/aaa/bbb 变为 https://abcsys.com:7777/aaa/bbb
        rewrite /devapi/(.*) /$1 break;
        proxy_pass https://abcsys.com:7777;
        proxy_set_header Host $host;
        proxy_method $request_method;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }

    location / {
        root   /usr/share/nginx/html;
        index  index.html index.htm;
        try_files $uri $uri/ /index.html;
        # 加这句是为例解决web部署后发生2次请求
        if ($request_uri ~ ^/devapi/) { 
            break;
        }
    }
}
相关推荐
cs_dn_Jie6 分钟前
钉钉 H5 微应用 手机端调试
前端·javascript·vue.js·vue·钉钉
开心工作室_kaic40 分钟前
ssm068海鲜自助餐厅系统+vue(论文+源码)_kaic
前端·javascript·vue.js
有梦想的刺儿1 小时前
webWorker基本用法
前端·javascript·vue.js
cy玩具1 小时前
点击评论详情,跳到评论页面,携带对象参数写法:
前端
清灵xmf2 小时前
TypeScript 类型进阶指南
javascript·typescript·泛型·t·infer
小白学大数据2 小时前
JavaScript重定向对网络爬虫的影响及处理
开发语言·javascript·数据库·爬虫
qq_390161772 小时前
防抖函数--应用场景及示例
前端·javascript
334554323 小时前
element动态表头合并表格
开发语言·javascript·ecmascript
John.liu_Test3 小时前
js下载excel示例demo
前端·javascript·excel
Yaml43 小时前
智能化健身房管理:Spring Boot与Vue的创新解决方案
前端·spring boot·后端·mysql·vue·健身房管理