赞
踩
这篇文章主要介绍uniapp
在Hbuilderx
中,通过工程化,区分不同环境、动态修改小程序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中点击运行和发行可以看到下面效果
这时就可以使用<!-- #ifdef MP-YYT -->
来实现在微信平台,区分不同主体的条件编译,通过环境变量process.env.NAME
取得配置文件中NAME
的信息
- 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'
- }
- }

其中变量名 cjnDev
、cjnTest
、cjnProd
等要跟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
在项目根目录的manifest.json
内,动态修改逻辑是使用nodejs
的fs
模块,通过方法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的值一致,这也是为什么我们前面强调:‘尽量保证yytProd
和NAME
值保持一致’的原因。
1. 本地调试运行:Hbuilder->运行,选择对应的自定义环境执行
2. 上线发布:Hbuilder->发行->自定义发行,选择对应的自定义环境执行
3. 业务开发通过`process.env.config[process.env.NAME]`获取对应环境的变量对象
赞
踩
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。