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

news/2024/7/7 22:29:55

前言

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

背景

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

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

一、自定义条件编译

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

<!-- #ifdef MP-WEIXIN -->
    <view>我是微信</view>
<!-- #endif -->
<!-- #ifdef H5 -->
    <view>我是后</view>
<!-- #endif -->

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

<!-- #ifdef MP-CJN -->
    <view>我是CJN</view>
<!-- #endif -->
<!-- #ifdef MP-YYT -->
    <view>我是YYT</view>
<!-- #endif -->

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

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

{
    "uni-app": {
        "scripts": {
            "cjnDev": {
                "title":"小程序1-联调环境",
                "env": {
                    "UNI_PLATFORM": "mp-weixin",
                    "NAME": "cjnDev"
                },
                "define": {
                    "MP-CJN": true
                }
            },
            "cjnTest": {
                "title":"小程序1-测试环境",
                "env": {
                    "UNI_PLATFORM": "mp-weixin",
                    "NAME": "cjnTest"
                },
                "define": {
                    "MP-CJN": true
                }
            },
            "cjnProd": {
                "title":"小程序1-生产环境",
                "env": {
                    "UNI_PLATFORM": "mp-weixin",
                    "NAME": "cjnProd"
                },
                "define": {
                    "MP-CJN": true
                }
            },
            "yytDev": {
                "title":"小程序2-联调环境",
                "env": {
                    "UNI_PLATFORM": "mp-weixin",
                    "NAME": "yytDev"
                },
                "define": {
                    "MP-YYT": true
                }
            },
            "yytTest": {
                "title":"小程序2-测试环境",
                "env": {
                    "UNI_PLATFORM": "mp-weixin",
                    "NAME": "yytTest"
                },
                "define": {
                    "MP-YYT": true
                }
            },
            "yytProd": {
                "title":"小程序2-生产环境",
                "env": {
                    "UNI_PLATFORM": "mp-weixin",
                    "NAME": "yytProd"
                },
                "define": {
                    "MP-YYT": true
                }
            }
        }    
    }
}

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

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

ee70d202403091044358594.png

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

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

module.exports = {
    // 小程序1联调环境
    cjnDev: {
        requestUrl: 'https://mp.com',
        appid: '小程序appid'
    },
    // 小程序1测试环境
    cjnTest: {
        requestUrl: '接口地址',
        appid: '小程序appid'
    },
    // 小程序1线上环境
    cjnProd: {
        requestUrl: '接口地址',
        appid: '小程序appid'
    }
    // 小程序2联调环境
    yytDev: {
        requestUrl: '接口地址',
        appid: '小程序appid'
    },
    // 小程序2测试环境
    yytTest: {
        requestUrl: '接口地址',
        appid: '小程序appid'
    },
    // 小程序2线上环境
    yytProd: {
        requestUrl: '接口地址',
        appid: '小程序appid'
    }
}

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

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

let configUrl = require('./common/env.js');
// 动态修改appid,调试环境时,可以先注释掉
require('./src/modifyManifest.js');
module.exports = {
    chainWebpack: config => {
      config
        .plugin('define')
        .tap(args => {
            args[0]['process.env.config'] = JSON.stringify(configUrl)
            return args
        })
    }
}

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

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

动态修appid

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

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

let configUrl = require('../common/env.js');
const fs = require('fs');
// 读取 manifest.json
const manifestPath = `${process.env.UNI_INPUT_DIR}/manifest.json`
let Manifest = fs.readFileSync(manifestPath, { encoding: 'utf-8' })
/**
 * 替换 manifest.json 文件内容
 * @param {String} path 目标元素的键
 * @param {String} value 目标元素的值
 */
function replaceManifest(path, value) {
    const arr = path.split('.')
    const len = arr.length
    const lastItem = arr[len - 1]

    let i = 0
    let ManifestArr = Manifest.split(/\n/)

    for (let index = 0; index < ManifestArr.length; index++) {
        const item = ManifestArr[index]
        if (new RegExp(`"${arr[i]}"`).test(item)) ++i;
        if (i === len) {
            const hasComma = /,/.test(item)
            ManifestArr[index] = item.replace(new RegExp(`"${lastItem}"[\\s\\S]*:[\\s\\S]*`), `"${lastItem}": ${typeof value === 'string'? '"'+value+'"' : value}${hasComma ? ',' : ''}`)
            break;
        }
    }

    Manifest = ManifestArr.join('\n')
}
// 替换appid
const appid = configUrl[process.env.UNI_SCRIPT].appid;
replaceManifest('mp-weixin.appid', appid);
// 文件输出
fs.writeFileSync(manifestPath, Manifest, {
  "flag": "w"
})

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

f84c8202403091043466109.png

三、使用方式

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

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

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


http://lihuaxi.xjx100.cn/news/2100840.html

相关文章

互动投影游戏如何为科普教育馆带来更加生动有趣的科普体验?

近年科普教育馆在数字多媒体技术的支持下&#xff0c;让更多的家长和孩子注意到这一展示场景&#xff0c;尤其是对孩子来说&#xff0c;这里不仅是一个扩展知识的场景&#xff0c;更是一个发掘自我、探索未知世界的地方&#xff0c;而在这个过程中&#xff0c;多媒体互动技术的…

GPT-1, GPT-2, GPT-3, InstructGPT / ChatGPT and GPT-4 总结

1. GPT-1 What the problem GPT-1 solve? 在 GPT-1 之前&#xff0c;NLP 通常是一种监督模型。 对于每个任务&#xff0c;都有一些标记数据&#xff0c;然后根据这些标记数据开发监督模型。 这种方法存在几个问题&#xff1a;首先&#xff0c;需要标记数据。 但 NLP 不像 CV&…

一个比较全面实用的C#帮助类、工具类库 - Common.Utility

前言 经常会有一些同学会问为什么感觉我身边的大佬写一个功能会这么快&#xff1f;一个类似的模块大佬可能半天就搞定了&#xff0c;而我要搞一两天。其实工作久了你会发现很多常用公共的帮助类和工具类&#xff0c;如常见的Excel数据导入导出、文件操作、字符串操作、数据转换…

Python3 字符编解码

Python3 字符编解码 什么是字符编解码 编码&#xff1a;根据编码格式将人类认识的字符转为字节流。解码&#xff1a;根据编码格式将字节流转为人类认识的字符。 Python3 中的字符编码 utf-8为Python3的默认编码格式&#xff0c;可通过以下语句查看&#xff1a; import sys p…

开源项目免费接口:观点抽取让数据分析更简单

一、开源项目介绍 一款多模态AI能力引擎&#xff0c;专注于提供自然语言处理&#xff08;NLP&#xff09;、情感分析、实体识别、图像识别与分类、OCR识别和语音识别等接口服务。该平台功能强大&#xff0c;支持本地化部署&#xff0c;并鼓励用户体验和开发者共同完善&#xf…

Linux下的多线程编程:原理、工具及应用(3)

&#x1f3ac;慕斯主页&#xff1a;修仙—别有洞天 ♈️今日夜电波&#xff1a;Flower of Life—陽花 0:34━━━━━━️&#x1f49f;──────── 4:46 &#x1f504; ◀️ ⏸ ▶️ ☰ …

学习Java十一天总结

目录 一、走进Java编程世界 二、变量、常量和运算符 三、if选择结构 四、switch选择结构 五、while循环结构 六、for循环结构 七、数组 八、深度循环结构 九、类和对象 十、类的无参方法 十一、类的带参方法 十二、字符串 一、走进Java编程世界 程序是为了让计算机…

题记(56)--L1-071 前世档案

目录 一、题目内容 二、输入描述 三、输出描述 四、输入输出示例 五、完整C语言代码 一、题目内容 网络世界中时常会遇到这类滑稽的算命小程序&#xff0c;实现原理很简单&#xff0c;随便设计几个问题&#xff0c;根据玩家对每个问题的回答选择一条判断树中的路径&#x…