当前位置:   article > 正文

一站式解决方案:uni-app条件编译及多环境配置,appid动态修改攻略!_uniapp 多环境配置

uniapp 多环境配置

前言

这篇文章主要介绍uniappHbuilderx 中,通过工程化,区分不同环境、动态修改小程序appid以及自定义条件编译,解决代码发布运行时手动切换到问题。

背景

在企业级的应用中,通常会分为,开发、联调、生产等多个环境,一个项目可能要发布到多个微信小程序,在工程化中,通过使用不同的打包命令设置不同的环境变量,解决不同环境各变量的内容需手动修改的问题,比如:接口、前缀、appid等;在使用uniapp开发项目时,通常使用Hbuilder可视化运行项目,点击运行编译出来都代码环境是(development),点击发布运行编译出来的代码是(production),分别对应开发和生产,使用process.env.NODE_ENV来获取运行环境。但是在很多企业项目中,就两个环境,很难满足使用场景。

为了解决以上问题,通过在package.json中增加增加 uni-app节点,自定义条件编译和环境,通过modifyManifest.js重写appid,扩展vue.config.js配置,用环境标识区分接口

一、自定义条件编译

以微信小程序为例,在做条件编译时候,只有一种判断条件

  1. <!-- #ifdef MP-WEIXIN -->
  2. <view>我是微信</view>
  3. <!-- #endif -->
  4. <!-- #ifdef H5 -->
  5. <view>我是后</view>
  6. <!-- #endif -->

但实际情况是,我们有两个微信主体,希望在不同主体展示不同信息:

  1. <!-- #ifdef MP-CJN -->
  2. <view>我是CJN</view>
  3. <!-- #endif -->
  4. <!-- #ifdef MP-YYT -->
  5. <view>我是YYT</view>
  6. <!-- #endif -->

package.json中新增uni-app官网自定义配置

实际使用时,删除掉文件中所有的注释信息,否则编译时会报错。

  1. {
  2. "uni-app": {
  3. "scripts": {
  4. "cjnDev": {
  5. "title":"小程序1-联调环境",
  6. "env": {
  7. "UNI_PLATFORM": "mp-weixin",
  8. "NAME": "cjnDev"
  9. },
  10. "define": {
  11. "MP-CJN": true
  12. }
  13. },
  14. "cjnTest": {
  15. "title":"小程序1-测试环境",
  16. "env": {
  17. "UNI_PLATFORM": "mp-weixin",
  18. "NAME": "cjnTest"
  19. },
  20. "define": {
  21. "MP-CJN": true
  22. }
  23. },
  24. "cjnProd": {
  25. "title":"小程序1-生产环境",
  26. "env": {
  27. "UNI_PLATFORM": "mp-weixin",
  28. "NAME": "cjnProd"
  29. },
  30. "define": {
  31. "MP-CJN": true
  32. }
  33. },
  34. "yytDev": {
  35. "title":"小程序2-联调环境",
  36. "env": {
  37. "UNI_PLATFORM": "mp-weixin",
  38. "NAME": "yytDev"
  39. },
  40. "define": {
  41. "MP-YYT": true
  42. }
  43. },
  44. "yytTest": {
  45. "title":"小程序2-测试环境",
  46. "env": {
  47. "UNI_PLATFORM": "mp-weixin",
  48. "NAME": "yytTest"
  49. },
  50. "define": {
  51. "MP-YYT": true
  52. }
  53. },
  54. "yytProd": {
  55. "title":"小程序2-生产环境",
  56. "env": {
  57. "UNI_PLATFORM": "mp-weixin",
  58. "NAME": "yytProd"
  59. },
  60. "define": {
  61. "MP-YYT": true
  62. }
  63. }
  64. }
  65. }
  66. }

注意:尽量保证yytProd和NAME值保持一致

以上代码以微信小程序在不同主体的展示为例,分别为小程序1(MP-CJN)、小程序2(MP-YYT),同时区分了三个环境,联调、测试和生产,配置好以后,我们在Hbuilder中点击运行和发行可以看到下面效果

ee70d202403091044358594.png

这时就可以使用<!-- #ifdef MP-YYT -->来实现在微信平台,区分不同主体的条件编译,通过环境变量process.env.NAME取得配置文件中NAME的信息

二、配置其他变量
创建`env.js`,存放相关环境变量的信息;我是在common中创建的,可以根据自己项目实际情况选择目录

  1. module.exports = {
  2. // 小程序1联调环境
  3. cjnDev: {
  4. requestUrl: 'https://mp.com',
  5. appid: '小程序appid'
  6. },
  7. // 小程序1测试环境
  8. cjnTest: {
  9. requestUrl: '接口地址',
  10. appid: '小程序appid'
  11. },
  12. // 小程序1线上环境
  13. cjnProd: {
  14. requestUrl: '接口地址',
  15. appid: '小程序appid'
  16. }
  17. // 小程序2联调环境
  18. yytDev: {
  19. requestUrl: '接口地址',
  20. appid: '小程序appid'
  21. },
  22. // 小程序2测试环境
  23. yytTest: {
  24. requestUrl: '接口地址',
  25. appid: '小程序appid'
  26. },
  27. // 小程序2线上环境
  28. yytProd: {
  29. requestUrl: '接口地址',
  30. appid: '小程序appid'
  31. }
  32. }

其中变量名 cjnDevcjnTestcjnProd等要跟package.json中的NAME一致,方便后续通过变量名取值。

在根目录下创建vue.config.js

  1. let configUrl = require('./common/env.js');
  2. // 动态修改appid,调试环境时,可以先注释掉
  3. require('./src/modifyManifest.js');
  4. module.exports = {
  5. chainWebpack: config => {
  6. config
  7. .plugin('define')
  8. .tap(args => {
  9. args[0]['process.env.config'] = JSON.stringify(configUrl)
  10. return args
  11. })
  12. }
  13. }

通过定义一个全局的变量process.env.config存储的就是env.js中的全部变量信息,此时就可以直接获取到当前运行所对应的配置信息

  1. // 运行小程序1-联调环境 获得:https://mp.com
  2. le url = process.env.config[process.env.NAME].requestUrl

动态修appid

appid在项目根目录的manifest.json内,动态修改逻辑是使用nodejsfs模块,通过方法readFileSync读取文件,然后跟进当前环境对内容进行修改,最后通过writeFileSync写入到manifest.json

src目录下创建modifyManifest.js划重点:一定得是在src目录下

  1. let configUrl = require('../common/env.js');
  2. const fs = require('fs');
  3. // 读取 manifest.json
  4. const manifestPath = `${process.env.UNI_INPUT_DIR}/manifest.json`
  5. let Manifest = fs.readFileSync(manifestPath, { encoding: 'utf-8' })
  6. /**
  7. * 替换 manifest.json 文件内容
  8. * @param {String} path 目标元素的键
  9. * @param {String} value 目标元素的值
  10. */
  11. function replaceManifest(path, value) {
  12. const arr = path.split('.')
  13. const len = arr.length
  14. const lastItem = arr[len - 1]
  15. let i = 0
  16. let ManifestArr = Manifest.split(/\n/)
  17. for (let index = 0; index < ManifestArr.length; index++) {
  18. const item = ManifestArr[index]
  19. if (new RegExp(`"${arr[i]}"`).test(item)) ++i;
  20. if (i === len) {
  21. const hasComma = /,/.test(item)
  22. ManifestArr[index] = item.replace(new RegExp(`"${lastItem}"[\\s\\S]*:[\\s\\S]*`), `"${lastItem}": ${typeof value === 'string'? '"'+value+'"' : value}${hasComma ? ',' : ''}`)
  23. break;
  24. }
  25. }
  26. Manifest = ManifestArr.join('\n')
  27. }
  28. // 替换appid
  29. const appid = configUrl[process.env.UNI_SCRIPT].appid;
  30. replaceManifest('mp-weixin.appid', appid);
  31. // 文件输出
  32. fs.writeFileSync(manifestPath, Manifest, {
  33. "flag": "w"
  34. })

关于环境变量,此时获取不到process.env.NAME,通过打印可以看到process.env.UNI_SCRIPT与NAME的值一致,这也是为什么我们前面强调:‘尽量保证yytProdNAME值保持一致’的原因。

f84c8202403091043466109.png

三、使用方式

1. 本地调试运行:Hbuilder->运行,选择对应的自定义环境执行

2. 上线发布:Hbuilder->发行->自定义发行,选择对应的自定义环境执行

3. 业务开发通过`process.env.config[process.env.NAME]`获取对应环境的变量对象

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/IT小白/article/detail/540343
推荐阅读