背景
在企業(yè)級項目開發(fā)中,一般都會分為開發(fā)、測試、預(yù)發(fā)布、生產(chǎn)等多個環(huán)境,在工程化中使用不同的打包命令改變環(huán)境變量解決不同環(huán)境各種變量需要手動修改的問題,比如接口請求地址,不同環(huán)境的請求路徑前綴都是不同的。在使用uni-app
開發(fā)項目時,一般都是選擇使用HbuilderX
可視化創(chuàng)建項目,也不建議使用cli
工程化方式創(chuàng)建uni-app
項目。在HbuilderX
中,默認只支持開發(fā)和生產(chǎn)兩個環(huán)境,點擊“運行”編譯出來的代碼是開發(fā)環(huán)境(development
),點擊“發(fā)行”編譯出來的代碼是生產(chǎn)環(huán)境(production
),可以通過process.env.NODE_ENV
獲取當(dāng)前環(huán)境。但在很多企業(yè)中,可能就2個環(huán)境并不能滿足實際場景,同時在開發(fā)微信小程序時,測試和生產(chǎn)都是不同的appid
,每次部署都要手動修改切換很容易出現(xiàn)問題。為了解決上述問題,通過在package.json
中增加uni-app
擴展節(jié)點,實現(xiàn)自定義條件編譯平臺,讓每種編譯具有不同環(huán)境標(biāo)識。再擴展vite.config.js
配置文件,用環(huán)境標(biāo)識判斷重寫文件中的appid
。
解決方案
一、創(chuàng)建基礎(chǔ)項目
選擇默認模板,注意vue版本選擇3
二、增加擴展節(jié)點
根據(jù)官方文檔說明,擴展節(jié)點配置說明如下:
{
/**
* package.json其它原有配置
* 拷貝代碼后請去掉注釋!
*/
"uni-app": {// 擴展配置
"scripts": {
"custom-platform": { //自定義編譯平臺配置,可通過cli方式調(diào)用
"title":"自定義擴展名稱", // 在HBuilderX中會顯示在 運行/發(fā)行 菜單中
"browser":"", //運行到的目標(biāo)瀏覽器,僅當(dāng)UNI_PLATFORM為h5時有效
"env": {//環(huán)境變量
"UNI_PLATFORM": "", //基準(zhǔn)平臺
"MY_TEST": "", // ... 其他自定義環(huán)境變量
},
"define": { //自定義條件編譯
"CUSTOM-CONST": true //自定義條件編譯常量,建議為大寫
}
}
}
}
}
注意:
-
UNI_PLATFORM
僅支持填寫uni-app
默認支持的基準(zhǔn)平臺,目前僅限如下枚舉值:h5
、mp-weixin
、mp-alipay
、mp-baidu
、mp-toutiao
、mp-qq
-
browser
僅在UNI_PLATFORM
為h5
時有效,目前僅限如下枚舉值:chrome
、firefox
、ie
、edge
、safari
、hbuilderx
-
package.json
文件中不允許出現(xiàn)注釋,否則擴展配置無效 -
vue-cli
需更新到最新版,HBuilderX需升級到 2.1.6+
實際使用時,暫時不用的變量直接刪除,新建package.json
文件,代碼如下:
{
"uni-app": {
"scripts": {
"wx-test": {
"title":"微信小程序 測試環(huán)境",
"env": {
"UNI_PLATFORM": "mp-weixin",
"NAME": "test"
}
},
"wx-prod": {
"title":"微信小程序 生產(chǎn)環(huán)境",
"env": {
"UNI_PLATFORM": "mp-weixin",
"NAME": "production"
}
},
"h5-dev": {
"title":"H5 開發(fā)環(huán)境",
"browser":"chrome",
"env": {
"UNI_PLATFORM": "h5",
"NAME": "development"
}
},
"h5-test": {
"title":"H5 測試環(huán)境",
"browser":"chrome",
"env": {
"UNI_PLATFORM": "h5",
"NAME": "test"
}
},
"h5-prod": {
"title":"H5 生產(chǎn)環(huán)境",
"browser":"chrome",
"env": {
"UNI_PLATFORM": "h5",
"NAME": "production"
}
}
}
}
}
上面代碼片段只以微信小程序和H5
兩個端為例,其中只增加了常量NAME
用于區(qū)分當(dāng)前環(huán)境,類似于process.env.NODE_ENV
獲取環(huán)境變量的作用。一般小程序也就測試和生產(chǎn)兩個環(huán)境,環(huán)境太多都要重新申請賬號也麻煩。H5
按照常規(guī)的配置本地開發(fā)、測試、生產(chǎn)三個環(huán)境。配置好后我們點擊頂部菜單欄的“運行”和“發(fā)行”即可看到效果。
當(dāng)在業(yè)務(wù)里需要使用添加的NAME
變量時,直接通過process.env.NAME
即可獲取。
四、配置其他變量
根目錄下新建config
目錄,用于放一些業(yè)務(wù)配置項,再新建環(huán)境相關(guān)變量配置文件env.js
,代碼如下:
// 不同的環(huán)境變量配置
const development = {
requestBaseUrl: 'http://development',
appid: '',
}
const test = {
requestBaseUrl: 'http://test',
appid: 'wxd5xxxxee0fce1c81',
}
const production = {
requestBaseUrl: 'http://production',
appid: 'wx3xxxx1ce403cab3',
}
export default {
development,
test,
production
}
其中變量對象名稱development
、test
、production
要和package.json
文件中定義的NAME
保持一致,方便后續(xù)通過對象方式直接取值。變量對象中添加的是需要根據(jù)不同環(huán)境配置的變量,比如后端服務(wù)請求地址,小程序appid
和一些別的插件key
。配置后我們就可以配合環(huán)境NAME
獲取到不同環(huán)境的其他變量了,簡單使用方式如下:
import ENV_CONFIG from '@/config/env.js'
console.log(ENV_CONFIG[process.env.NAME].requestBaseUrl) // 運行H5 開發(fā)環(huán)境結(jié)果 http://development
每次引入獲取方式肯定不夠友好,在uni-app
中還可以通過修改vite
配置添加全局變量,更方便在全局使用。
首先根目錄下新建vite.config.js
文件,內(nèi)容如下:
import { defineConfig } from 'vite'
import uni from '@dcloudio/vite-plugin-uni'
import ENV_CONFIG from './env/index.js'
export default defineConfig({
plugins: [uni()],
define: {
'process.env.config': ENV_CONFIG,
},
});
通過定義一個全局變量process.env.config
,賦值為ENV_CONFIG
,process.env.config
可以改為任何一個字符串,這里主要是為了保持和默認通過process.env
獲取環(huán)境變量的語義一致性。此時使用時就無需在業(yè)務(wù)中單獨引入,從全局對象process.env.config
上取值即可:
console.log(process.env.config[process.env.NAME].requestBaseUrl) // 運行H5 開發(fā)環(huán)境結(jié)果 http://development
五、動態(tài)修改小程序appid
appid
是在根目錄下的manifest.json
文件中,點擊后最下面有源碼視圖。修改的方式就是運用node
的fs
模塊,先讀取manifest.json
文件,然后根據(jù)當(dāng)前環(huán)境,動態(tài)替換掉appid
或者其他參數(shù),最后重新寫入到當(dāng)前目錄下。具體也是在vite.config.js
中處理:
import { defineConfig } from 'vite';
import uni from '@dcloudio/vite-plugin-uni';
import ENV_CONFIG from './config/env.js'
// 引入fs模塊
import fs from 'fs'
// 讀取 manifest.json ,修改后重新寫入
const manifestPath = `${__dirname}/manifest.json`;
let Manifest = fs.readFileSync(manifestPath, { encoding: 'utf-8' });
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');
}
// 具體使用,找到對應(yīng)key值替換為新的值
// replaceManifest('app-plus.usingComponents', false);
const appid = ENV_CONFIG[JSON.parse(process.env.UNI_CUSTOM_DEFINE).NAME].appid
replaceManifest('mp-weixin.appid', appid);
fs.writeFileSync(manifestPath, Manifest, { flag: 'w' });
export default defineConfig({
plugins: [uni()],
define: {
'process.env.config': ENV_CONFIG,
},
});
這個修改方案是根據(jù)官方提供的代碼片段修改,其中進行了一些變動:
-
manifest.json
文件路徑由相對路徑改為__dirname
獲取的絕對路徑 -
replaceManifest
方法中的value進行了typeof
類型判斷,如果是字符串加上雙引號。因為測試時傳個字符串會替換成沒引號的變量或者數(shù)字
同時關(guān)于當(dāng)前環(huán)境變量的獲取,此時通過process.env.NAME
是獲取不到package.json
配置的NAME
的,通過打印process.env
可以發(fā)現(xiàn)此時它是個包含很多變量的json
,在UNI_CUSTOM_DEFINE
下面是可以找到NAME
,這樣就能根據(jù)不同環(huán)境獲取不同的appid
。
然后也可以用下面這種更容易理解的方式修改manifest.json
,但是修改后內(nèi)容排在一行,想要美觀還需要手動格式化。文章來源:http://www.zghlxwxcb.cn/news/detail-658614.html
// appid獲取只做參考,這里只是說明簡單的只有兩個環(huán)境,可以直接取process.env.NODE_ENV判斷
let appid = process.env.NODE_ENV == "production" ? '生產(chǎn)的appid' : "開發(fā)的appid"
// manifest.json 路徑
let manifestFileUrl = `${__dirname}/manifest.json`
// 讀取文件數(shù)據(jù)
let manifestFileData = fs.readFileSync(manifestFileUrl, { encoding: 'utf8' });
// 移除// 和 /* */注釋
manifestFileData = manifestFileData.replace(/\\"|"(?:\\"|[^"])*"|(\/\/.*|\/\*[\s\S]*?\*\/)/g, (m, g) => g ? "" : m)
// // 將txt轉(zhuǎn)成obj
let manifestFileDataObj = JSON.parse(manifestFileData)
// 修改指定key對應(yīng)的value
manifestFileDataObj['mp-weixin']['appid'] = appid
// 把修改后的對象以json寫入文件
fs.writeFileSync(manifestFileUrl, JSON.stringify(manifestFileDataObj), { encoding: 'utf8' })
六、使用方式
- 需要本地調(diào)試時,點擊工具欄“運行”,選擇自定義的對應(yīng)開發(fā)或測試環(huán)境;
- 業(yè)務(wù)中通過
process.env.config[process.env.NAME]
獲取配置的變量對象; - 上線時,點擊工具欄“發(fā)行”,選擇自定義的對應(yīng)測試或生產(chǎn)環(huán)境;
運行環(huán)境
以上代碼是運行在Hbuilderx 3.7.9
版本,項目為vue3
版本,基于vite
構(gòu)建。如在vue2
版本上使用,請按照vite.config.js
邏輯自行探索配置vue.config.js
文件。文章來源地址http://www.zghlxwxcb.cn/news/detail-658614.html
到了這里,關(guān)于uni-app自定義多環(huán)境配置,動態(tài)修改appid的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!