境變量配置實(shí)戰(zhàn):多端構(gòu)建與安全部署指南)
1. 項(xiàng)目概述為什么環(huán)境變量是跨端開發(fā)的“命門”最近在帶幾個(gè)新人做UniApp項(xiàng)目發(fā)現(xiàn)一個(gè)挺普遍的問題大家本地開發(fā)跑得好好的一到測試或生產(chǎn)環(huán)境接口地址、AppID、密鑰這些就全亂套了要么就是打包后配置沒生效要么就是不同環(huán)境配置混在一起。追根溯源問題往往出在環(huán)境變量配置這個(gè)基礎(chǔ)環(huán)節(jié)上。很多人覺得這不過是幾個(gè)配置文件照著教程配一下就行但真到了多環(huán)境、跨平臺H5、小程序、App的UniApp Vue3 Vite項(xiàng)目里這里面的門道可不少。環(huán)境變量本質(zhì)上是一套“運(yùn)行時(shí)注入”的配置管理方案。它允許我們將與環(huán)境相關(guān)的配置如API基地址、調(diào)試開關(guān)、第三方密鑰從代碼中剝離出來實(shí)現(xiàn)“一份代碼多處部署”。對于UniApp這種一次開發(fā)、多端發(fā)布的框架來說這一點(diǎn)尤為重要。想象一下你的應(yīng)用需要對接的后端API在開發(fā)時(shí)可能是http://localhost:3000測試環(huán)境是https://test-api.example.com而上線后則是https://api.example.com。如果這些地址硬編碼在代碼里每次切換環(huán)境都得改代碼、重新打包不僅效率低下而且極易出錯(cuò)。Vue3 Vite的組合為現(xiàn)代前端開發(fā)帶來了極致的開發(fā)體驗(yàn)其基于ES模塊的原生支持使得模塊熱更新HMR速度飛快。Vite在處理環(huán)境變量時(shí)也有一套自己的約定和構(gòu)建時(shí)替換機(jī)制。但UniApp作為一個(gè)上層框架它對構(gòu)建流程有自己的一套封裝和擴(kuò)展特別是在處理多平臺如微信小程序、App時(shí)其構(gòu)建目標(biāo)和過程與純Web項(xiàng)目有所不同。這就導(dǎo)致了一個(gè)常見的困境直接套用Vite或Vue CLI那套環(huán)境變量配置方法在UniApp里可能行不通或者只在H5端生效到了小程序和App端就“失靈”了。因此理清在UniApp Vue3 Vite技術(shù)棧下環(huán)境變量如何正確配置、如何在代碼中安全獲取、以及如何適配多端構(gòu)建就成了一個(gè)必須扎實(shí)掌握的核心技能。這不僅僅是配幾個(gè)文件那么簡單它關(guān)系到項(xiàng)目的可維護(hù)性、團(tuán)隊(duì)協(xié)作的規(guī)范性以及最終交付的可靠性。接下來我就結(jié)合最近幾個(gè)項(xiàng)目的實(shí)戰(zhàn)經(jīng)驗(yàn)把這套配置體系的思路、具體做法和踩過的坑系統(tǒng)地梳理一遍。2. 環(huán)境變量配置的核心思路與方案選型在開始動(dòng)手寫配置之前我們必須先想清楚目標(biāo)我們需要一套怎樣的環(huán)境變量管理方案結(jié)合UniApp多端發(fā)行的特點(diǎn)我認(rèn)為一個(gè)理想的方案需要滿足以下幾個(gè)核心需求環(huán)境隔離清晰地區(qū)分開發(fā)development、測試staging、生產(chǎn)production等不同環(huán)境互不干擾。多端一致配置方案需要在H5、各家小程序微信、支付寶等、AppiOS/Android等所有UniApp支持的目標(biāo)平臺上都生效。安全可控敏感信息如密鑰不應(yīng)出現(xiàn)在前端代碼倉庫中而應(yīng)通過安全的渠道注入。開發(fā)友好在開發(fā)時(shí)能方便地切換和預(yù)覽不同環(huán)境的效果且支持熱更新。構(gòu)建集成能無縫融入Vite的構(gòu)建流程并正確參與UniApp特有的編譯過程?;谶@些需求直接使用Vite原生環(huán)境變量.env文件是起點(diǎn)但并非終點(diǎn)。Vite使用dotenv從項(xiàng)目根目錄的.env文件中加載環(huán)境變量并通過import.meta.env對象暴露給客戶端代碼。這是Vite的標(biāo)準(zhǔn)做法在純Web項(xiàng)目中工作良好。然而UniApp的構(gòu)建過程比純Web項(xiàng)目復(fù)雜。當(dāng)你運(yùn)行npm run dev:mp-weixin開發(fā)微信小程序時(shí)UniApp CLI會調(diào)用Vite如果你配置了Vite模式進(jìn)行源碼編譯但最終生成的是小程序的代碼結(jié)構(gòu)。在這個(gè)過程中Vite的環(huán)境變量替換是發(fā)生在源碼編譯階段的。問題在于UniApp編譯到不同平臺時(shí)可能會對源碼進(jìn)行特定的轉(zhuǎn)換和封裝import.meta.env這個(gè)ES模塊的元屬性在某些平臺特別是小程序環(huán)境其JavaScript運(yùn)行環(huán)境并非標(biāo)準(zhǔn)的瀏覽器或Node可能無法被正確識別或訪問。因此更穩(wěn)健的方案是采用一種“雙軌制”或“適配層”的思路構(gòu)建時(shí)注入利用Vite的define配置將環(huán)境變量在構(gòu)建時(shí)靜態(tài)替換為具體的值。這樣最終生成的代碼里直接就是字符串常量不依賴于運(yùn)行時(shí)的import.meta.env對象兼容性最好。運(yùn)行時(shí)封裝同時(shí)我們也可以創(chuàng)建一個(gè)統(tǒng)一的配置模塊根據(jù)構(gòu)建模式或平臺特性安全地讀取環(huán)境變量并提供統(tǒng)一的API給業(yè)務(wù)代碼使用。經(jīng)過多個(gè)項(xiàng)目的實(shí)踐我總結(jié)出一套以“Vite環(huán)境變量文件為源通過define進(jìn)行構(gòu)建時(shí)替換并輔以統(tǒng)一配置模塊”為核心的配置方案。這套方案能較好地平衡靈活性、兼容性和安全性。2.1 方案對比與決策在具體實(shí)施前我們簡單對比幾種常見做法方案優(yōu)點(diǎn)缺點(diǎn)適用場景純import.meta.envVite原生支持簡單直接在小程序/App端可能無法訪問變量值在構(gòu)建后仍可能被查看非敏感信息可接受純H5項(xiàng)目或僅用于非敏感、非關(guān)鍵的配置Vitedefine替換構(gòu)建時(shí)靜態(tài)替換生成字面量兼容性極佳可混淆敏感值需要預(yù)先明確所有變量名熱更新需要重啟服務(wù)修改.env文件時(shí)UniApp多端項(xiàng)目推薦尤其適合需要跨平臺穩(wěn)定運(yùn)行的配置運(yùn)行時(shí)HTTP請求加載配置可動(dòng)態(tài)更新無需重新打包增加首屏加載依賴和復(fù)雜度需要處理加載失敗和等待狀態(tài)配置需要頻繁變動(dòng)的后臺管理系統(tǒng)或微前端場景平臺條件編譯UniApp原生支持可針對不同平臺寫死不同配置配置散落在代碼中難以維護(hù)無法根據(jù)構(gòu)建環(huán)境dev/prod切換僅用于平臺特性差異極大的配置不推薦用于環(huán)境變量對于大多數(shù)UniApp項(xiàng)目“Vitedefine替換”為主“統(tǒng)一配置模塊”為輔的方案是最佳實(shí)踐。它確保了配置在構(gòu)建階段就被確定并固化到產(chǎn)物中避免了運(yùn)行時(shí)的兼容性問題同時(shí)通過配置模塊提供了清晰的接口。3. 項(xiàng)目結(jié)構(gòu)與環(huán)境變量文件設(shè)計(jì)明確了方案我們先來規(guī)劃項(xiàng)目的目錄結(jié)構(gòu)和環(huán)境變量文件。一個(gè)清晰的結(jié)構(gòu)是后續(xù)一切操作的基礎(chǔ)。3.1 目錄結(jié)構(gòu)規(guī)劃我建議在項(xiàng)目根目錄下創(chuàng)建env文件夾或直接放在根目錄專門管理環(huán)境變量相關(guān)文件。一個(gè)典型的結(jié)構(gòu)如下your-uniapp-project/ ├── env/ # 環(huán)境變量目錄 │ ├── .env.development # 開發(fā)環(huán)境 │ ├── .env.staging # 測試環(huán)境 │ ├── .env.production # 生產(chǎn)環(huán)境 │ └── .env # 所有環(huán)境的默認(rèn)值可選 ├── src/ ├── vite.config.ts # Vite 配置文件 ├── manifest.json # UniApp 應(yīng)用配置 └── package.json注意.env文件通常包含敏感信息務(wù)必將其添加到.gitignore中避免提交到代碼倉庫??梢詫?env.example或.env.local僅包含變量名不含真實(shí)值提交供團(tuán)隊(duì)成員參考。3.2 環(huán)境變量文件內(nèi)容示例每個(gè).env.[mode]文件對應(yīng)一種構(gòu)建模式mode。Vite默認(rèn)會根據(jù)你運(yùn)行的命令如vite、vite build自動(dòng)加載對應(yīng)的文件。在UniApp中我們需要在package.json的 scripts 里指定模式。env/.env.development(開發(fā)環(huán)境)# 開發(fā)環(huán)境配置 VITE_APP_TITLE 我的應(yīng)用(開發(fā)版) VITE_API_BASE_URL https://dev-api.example.com VITE_APP_DEBUG true VITE_WEIXIN_APPID wx1234567890abcdef # 開發(fā)用小程序AppIDenv/.env.staging(測試環(huán)境)# 測試環(huán)境配置 VITE_APP_TITLE 我的應(yīng)用(測試版) VITE_API_BASE_URL https://staging-api.example.com VITE_APP_DEBUG true VITE_WEIXIN_APPID wxstaging1234567890env/.env.production(生產(chǎn)環(huán)境)# 生產(chǎn)環(huán)境配置 VITE_APP_TITLE 我的應(yīng)用 VITE_API_BASE_URL https://api.example.com VITE_APP_DEBUG false VITE_WEIXIN_APPID wxproduction1234567890關(guān)鍵規(guī)則說明變量命名為了在客戶端代碼中能夠被Vite捕獲并處理自定義環(huán)境變量必須以VITE_開頭。這是Vite的強(qiáng)制約定否則變量不會被載入import.meta.env。值類型等號右邊的值會被解析為字符串。true或false在代碼中獲取時(shí)會是字符串true或false需要自行轉(zhuǎn)換。模式覆蓋Vite啟動(dòng)時(shí)會先加載.env文件所有模式共享然后根據(jù)--mode指定的模式加載對應(yīng)的.env.[mode]文件后者會覆蓋前者的同名變量。4. 核心配置Vite與UniApp的融合這是整個(gè)配置過程中最關(guān)鍵的一步我們需要修改vite.config.ts文件讓Vite在構(gòu)建UniApp時(shí)正確地將環(huán)境變量“注入”到最終代碼中。4.1 修改vite.config.ts配置文件首先需要安裝types/node以便在Vite配置中使用process等Node.js模塊如果尚未安裝npm install -D types/node然后在vite.config.ts中我們需要做兩件事使用loadEnv函數(shù)加載指定模式的環(huán)境變量。通過define選項(xiàng)將環(huán)境變量定義為全局常量。// vite.config.ts import { defineConfig, loadEnv } from vite; import uni from dcloudio/vite-plugin-uni; import path from path; // https://vitejs.dev/config/ export default defineConfig(({ mode, command }) { // 1. 加載環(huán)境變量 // process.cwd() 返回項(xiàng)目根目錄 // 第三個(gè)參數(shù) 表示加載所有以 VITE_ 開頭的變量 const env loadEnv(mode, process.cwd() /env, ); // 注意我們指定了env目錄 // 2. 準(zhǔn)備需要注入的 define 對象 const define {} as Recordstring, any; // 遍歷所有以 VITE_ 開頭的環(huán)境變量將其注入 for (const key in env) { if (key.startsWith(VITE_)) { // 注意這里值需要 JSON.stringify因?yàn)?define 是做字符串替換 // 例如VITE_API_BASE_URL: https://api.com 會被替換為 https://api.com define[import.meta.env.${key}] JSON.stringify(env[key]); } } // 也可以注入一些通用的、非 VITE_ 前綴的變量或方便使用的別名 define[import.meta.env.MODE] JSON.stringify(mode); define[import.meta.env.PROD] JSON.stringify(command build); define[import.meta.env.DEV] JSON.stringify(command ! build); return { plugins: [uni()], // 3. 定義全局常量替換 define, // 其他配置如resolve.alias... resolve: { alias: { : path.resolve(__dirname, src), }, }, }; });這段配置的核心邏輯解釋loadEnv(mode, process.cwd() /env, )從項(xiàng)目根目錄下的/env文件夾中加載對應(yīng)模式mode的環(huán)境變量。作為第三個(gè)參數(shù)意味著我們只加載前綴為即所有的變量但實(shí)際上我們后續(xù)通過if (key.startsWith(VITE_))進(jìn)行了過濾這是一種更靈活的控制方式。你也可以直接寫loadEnv(mode, process.cwd() /env, VITE_)來只加載VITE_開頭的變量。define對象這是Vite的配置項(xiàng)它會在構(gòu)建階段將代碼中出現(xiàn)的define對象的鍵如import.meta.env.VITE_API_BASE_URL直接替換為對應(yīng)的值如https://api.example.com。這是一個(gè)靜態(tài)文本替換的過程替換后的代碼里不再有import.meta.env這個(gè)引用因此兼容性極高。JSON.stringify()這是必須的。因?yàn)閐efine是做簡單的字符串替換。如果不加JSON.stringify()假設(shè)env[key]是https://api.com替換后代碼會變成import.meta.env.VITE_API_BASE_URL https://api.com這缺少引號會導(dǎo)致語法錯(cuò)誤。經(jīng)過JSON.stringify()后值變成了https://api.com帶雙引號的字符串替換后代碼語法正確。4.2 修改package.json的 scripts接下來我們需要修改package.json中的啟動(dòng)和構(gòu)建腳本通過--mode參數(shù)指定要使用的環(huán)境模式。{ scripts: { dev:h5: uni -p h5 --mode development, build:h5: uni build -p h5 --mode production, dev:mp-weixin: uni -p mp-weixin --mode development, build:mp-weixin: uni build -p mp-weixin --mode production, dev:app: uni -p app --mode development, build:app: uni build -p app --mode production, // 可以添加自定義模式如測試環(huán)境 build:staging:h5: uni build -p h5 --mode staging, build:staging:mp-weixin: uni build -p mp-weixin --mode staging } }關(guān)鍵點(diǎn)--mode development告訴Vite使用development模式從而加載env/.env.development文件。--mode production對應(yīng)加載env/.env.production。--mode staging對應(yīng)加載env/.env.staging這是我們自定義的模式。現(xiàn)在當(dāng)你運(yùn)行npm run dev:mp-weixin時(shí)Vite就會加載開發(fā)環(huán)境的變量并注入到代碼中。5. 在代碼中安全、優(yōu)雅地使用環(huán)境變量配置好了構(gòu)建過程接下來就是在業(yè)務(wù)代碼中使用了。雖然經(jīng)過define替換后我們可以直接使用import.meta.env.VITE_XXX但為了更好的類型提示、默認(rèn)值處理和統(tǒng)一管理我強(qiáng)烈建議創(chuàng)建一個(gè)專門的配置模塊。5.1 創(chuàng)建統(tǒng)一的環(huán)境配置模塊在src目錄下創(chuàng)建config文件夾并新建env.ts文件// src/config/env.ts /** * 應(yīng)用運(yùn)行環(huán)境類型 */ export type AppEnv development | staging | production; /** * 獲取當(dāng)前構(gòu)建模式 * 通過 import.meta.env.MODE 獲取該值已在 vite.config.ts 中通過 define 注入 */ export const getEnvMode (): AppEnv { const mode import.meta.env.MODE as string; if ([development, staging, production].includes(mode)) { return mode as AppEnv; } // 默認(rèn)返回生產(chǎn)環(huán)境確保線上安全 return production; }; /** * 應(yīng)用配置對象 * 所有環(huán)境變量在此集中定義并提供類型安全和默認(rèn)值 */ const appConfig { // 應(yīng)用標(biāo)題 title: import.meta.env.VITE_APP_TITLE || UniApp, // API 基礎(chǔ)地址 apiBaseUrl: import.meta.env.VITE_API_BASE_URL || , // 是否調(diào)試模式 isDebug: (import.meta.env.VITE_APP_DEBUG || false) true, // 微信小程序 AppID (如果需要) weixinAppId: import.meta.env.VITE_WEIXIN_APPID || , // 當(dāng)前環(huán)境模式 mode: getEnvMode(), // 是否是生產(chǎn)環(huán)境 isProd: import.meta.env.PROD true, // 是否是開發(fā)環(huán)境 isDev: import.meta.env.DEV true, } as const; // 導(dǎo)出一個(gè)凍結(jié)的對象防止意外修改 export default Object.freeze(appConfig);這個(gè)模塊的優(yōu)勢類型安全為配置對象提供了明確的類型定義。默認(rèn)值處理避免了環(huán)境變量未定義導(dǎo)致的undefined錯(cuò)誤。邏輯轉(zhuǎn)換將字符串類型的VITE_APP_DEBUG轉(zhuǎn)換為布爾值isDebug使用起來更直觀。集中管理所有配置在一個(gè)地方方便查找和修改。只讀保證通過Object.freeze防止運(yùn)行時(shí)意外修改配置。5.2 在業(yè)務(wù)代碼中使用配置現(xiàn)在在Vue組件、Composables或工具函數(shù)中你可以像下面這樣使用script setup langts import { ref, onMounted } from vue; import envConfig from /config/env; // 使用別名指向src // 直接使用配置 const appTitle ref(envConfig.title); const apiBaseUrl envConfig.apiBaseUrl; onMounted(() { console.log(當(dāng)前環(huán)境: ${envConfig.mode}); console.log(API地址: ${apiBaseUrl}); if (envConfig.isDebug) { console.warn(當(dāng)前處于調(diào)試模式請注意控制臺信息。); } // 發(fā)起網(wǎng)絡(luò)請求示例 fetch(${apiBaseUrl}/user/profile) .then(res res.json()) .then(data console.log(data)); }); /script template view text{{ appTitle }}/text !-- ... -- /view /template5.3 處理平臺特定配置有時(shí)某些配置可能因平臺而異。例如微信小程序的AppID在H5環(huán)境下是無用的。我們可以在配置模塊中增加平臺判斷邏輯。UniApp提供了uni.getSystemInfoSync().platform或條件編譯。方法一運(yùn)行時(shí)判斷適用于邏輯簡單的場景// 在 env.ts 中補(bǔ)充 import { getSystemInfoSync } from uni-get-system-info; // 或使用 uni.getSystemInfoSync const systemInfo getSystemInfoSync(); const isWeixinMiniProgram systemInfo.platform devtools || systemInfo.platform wechat; // 需精確判斷 export const platformConfig { // 可以在這里根據(jù)平臺返回不同的值 getAppId() { if (isWeixinMiniProgram) { return envConfig.weixinAppId; } return ; } };方法二條件編譯更徹底代碼更清晰條件編譯是UniApp的強(qiáng)項(xiàng)適合平臺差異大的配置。// src/config/env.ts let platformSpecificApi ; // #ifdef H5 platformSpecificApi /h5-api-proxy; // #endif // #ifdef MP-WEIXIN platformSpecificApi https://api.weixin.qq.com; // #endif // #ifdef APP platformSpecificApi envConfig.apiBaseUrl; // App可能用同一個(gè) // #endif const appConfig { // ... 其他配置 platformApi: platformSpecificApi, };重要提示條件編譯的注釋 (// #ifdef) 是UniApp編譯器識別的特殊注釋它們會在編譯到特定平臺時(shí)被保留或移除。這確保了最終每個(gè)平臺的代碼只包含自己需要的部分。6. 多環(huán)境構(gòu)建與部署實(shí)戰(zhàn)配置寫好了最終我們要打包部署。不同環(huán)境對應(yīng)不同的命令和產(chǎn)物。6.1 配置 package.json scripts如前所述我們在package.json中已經(jīng)配置了不同模式和平臺的腳本。例如開發(fā)微信小程序npm run dev:mp-weixin(使用.env.development)構(gòu)建生產(chǎn)環(huán)境H5npm run build:h5(使用.env.production)構(gòu)建測試環(huán)境微信小程序npm run build:staging:mp-weixin(使用.env.staging)6.2 構(gòu)建產(chǎn)物驗(yàn)證構(gòu)建完成后如何確認(rèn)環(huán)境變量正確注入了呢由于define是靜態(tài)替換我們可以檢查構(gòu)建出的代碼文件。對于H5檢查dist/build/h5目錄下的.js文件。搜索你定義的變量名例如VITE_API_BASE_URL你應(yīng)該會發(fā)現(xiàn)它已經(jīng)被替換成了具體的字符串值而不是import.meta.env.VITE_API_BASE_URL。對于小程序檢查dist/dev/mp-weixin或dist/build/mp-weixin目錄下的.js文件如app.js或頁面js。同樣搜索變量名確認(rèn)已被替換。一個(gè)快速驗(yàn)證的方法在你的配置模塊env.ts中添加一個(gè)在控制臺打印配置的語句僅在開發(fā)環(huán)境if (import.meta.env.DEV) { console.log([Env Config], appConfig); }在開發(fā)時(shí)瀏覽器或開發(fā)者工具控制臺會輸出完整的配置對象。在構(gòu)建生產(chǎn)包時(shí)由于import.meta.env.DEV被替換為false這段代碼不會被執(zhí)行不會泄露信息。6.3 敏感信息處理與安全建議絕對不要將真實(shí)的密鑰、密碼等敏感信息提交到代碼倉庫即使是測試環(huán)境的。使用.env.local或個(gè)人環(huán)境文件創(chuàng)建.env.local文件并加入.gitignore。在vite.config.ts中可以調(diào)整loadEnv邏輯優(yōu)先加載本地覆蓋文件。// 簡化示例Vite本身支持 .env.local 覆蓋 .env // 確保 .gitignore 包含 .env.local const env loadEnv(mode, process.cwd() /env, );CI/CD 管道注入在 Jenkins、GitLab CI、GitHub Actions 等持續(xù)集成/部署平臺中將敏感信息設(shè)置為流水線的“機(jī)密變量”。在構(gòu)建腳本中通過命令行參數(shù)或環(huán)境變量動(dòng)態(tài)生成.env.production文件。# 示例在CI腳本中 echo VITE_API_BASE_URL$PRODUCTION_API_URL ./env/.env.production echo VITE_APP_KEY$PRODUCTION_APP_KEY ./env/.env.production npm run build:h5后端代理與鑒權(quán)最安全的做法是所有涉及敏感操作或數(shù)據(jù)的請求都不應(yīng)該依賴前端環(huán)境變量中的密鑰。前端只持有用于標(biāo)識自身如AppID的非敏感信息具體的密鑰應(yīng)由后端服務(wù)器保管前端通過安全的鑒權(quán)流程如OAuth 2.0獲取訪問令牌。7. 常見問題、排查技巧與實(shí)戰(zhàn)心得在實(shí)際項(xiàng)目中環(huán)境變量配置看似簡單卻容易遇到各種“坑”。下面是我總結(jié)的一些典型問題及解決方法。7.1 問題排查清單問題現(xiàn)象可能原因排查步驟與解決方案環(huán)境變量undefined1. 變量名不是以VITE_開頭。2..env文件未放在正確目錄或文件名與--mode不匹配。3.vite.config.ts中的loadEnv路徑或前綴參數(shù)錯(cuò)誤。4.define配置未正確注入該變量。1. 檢查變量名確保以VITE_開頭。2. 檢查package.json腳本中的--mode參數(shù)確認(rèn)對應(yīng)的.env.[mode]文件存在且路徑正確。3. 在vite.config.ts中console.log(env)打印加載的環(huán)境變量對象確認(rèn)是否加載成功。4. 檢查define對象中是否包含了該變量的鍵值對。H5正常小程序/App異常1. 代碼中直接使用import.meta.env.VITE_XXX但該對象在小程序環(huán)境不可用。2. 未使用define進(jìn)行構(gòu)建時(shí)替換。確保使用了define配置。這是解決多端兼容性的關(guān)鍵。構(gòu)建后檢查小程序產(chǎn)物的js文件確認(rèn)變量已被替換為字面量。修改.env文件后熱更新不生效Vite 的環(huán)境變量熱更新僅在服務(wù)啟動(dòng)時(shí)讀取。define配置的替換是靜態(tài)的。重啟開發(fā)服務(wù)器。修改.env文件后需要停止并重新運(yùn)行npm run dev:*命令。類型錯(cuò)誤import.meta.env上不存在屬性TypeScript 無法識別自定義的VITE_變量。在src目錄下創(chuàng)建env.d.ts文件進(jìn)行類型聲明interface ImportMetaEnv { readonly VITE_APP_TITLE: string; readonly VITE_API_BASE_URL: string; }構(gòu)建后代碼中仍存在process.env項(xiàng)目中可能混用了Webpack或Node.js的process.env寫法。UniApp Vite 項(xiàng)目應(yīng)統(tǒng)一使用import.meta.env。全局搜索process.env并替換。Vite的define也可以用于替換process.env.NODE_ENV等。不同開發(fā)者本地環(huán)境不一致.env.development文件被意外提交并覆蓋或者各自本地有未跟蹤的配置。1.確保.env*.local和.env.development等在.gitignore中。2. 提交一個(gè).env.example文件列出所有需要的變量名不含值供團(tuán)隊(duì)成員復(fù)制參考。3. 考慮使用dotenv庫在代碼中顯式加載指定路徑的文件但不如Vite集成方案優(yōu)雅。7.2 實(shí)戰(zhàn)心得與技巧環(huán)境變量命名規(guī)范化團(tuán)隊(duì)內(nèi)部制定規(guī)范例如VITE_APP_前綴表示應(yīng)用級配置VITE_API_前綴表示接口相關(guān)VITE_THIRD_表示第三方服務(wù)。一目了然便于管理。為配置模塊編寫單元測試雖然配置簡單但寫個(gè)簡單的測試用例來驗(yàn)證getEnvMode()函數(shù)在不同import.meta.env.MODE值下的返回以及配置對象的默認(rèn)值邏輯能有效防止后續(xù)修改時(shí)引入錯(cuò)誤。善用條件編譯處理平臺差異對于真正因平臺而異的配置如圖片上傳的API、社交分享的SDK初始化參數(shù)使用// #ifdef條件編譯比在運(yùn)行時(shí)通過if-else判斷更干凈還能減少無用代碼被打包到其他平臺。構(gòu)建腳本自動(dòng)化在package.json的 scripts 中可以組合命令。例如先清理舊構(gòu)建產(chǎn)物再執(zhí)行構(gòu)建scripts: { clean: rimraf dist, build:prod:h5: npm run clean uni build -p h5 --mode production, }需要安裝rimraf包npm i -D rimraf關(guān)注vite.config.ts的緩存有時(shí)修改了vite.config.ts但感覺沒生效可能是Vite的緩存問題。可以嘗試在啟動(dòng)命令后加上--force選項(xiàng)或者刪除node_modules/.vite緩存目錄。7.3 類型聲明的完善為了讓TypeScript更好地支持我們的環(huán)境變量創(chuàng)建src/env.d.ts文件// src/env.d.ts /// reference typesvite/client / // 擴(kuò)展 ImportMetaEnv 接口定義自定義環(huán)境變量的類型 interface ImportMetaEnv { // 每個(gè)變量都應(yīng)該是只讀的 readonly VITE_APP_TITLE: string readonly VITE_API_BASE_URL: string readonly VITE_APP_DEBUG: string // 注意從.env讀取的是字符串 readonly VITE_WEIXIN_APPID: string // 添加更多變量... } interface ImportMeta { readonly env: ImportMetaEnv }完成這一步后你在代碼中鍵入import.meta.env.IDE就會自動(dòng)提示出VITE_APP_TITLE等變量并且有正確的類型約束。經(jīng)過以上從思路到實(shí)踐從配置到排查的完整梳理相信你已經(jīng)能夠駕馭UniApp Vue3 Vite項(xiàng)目中的環(huán)境變量配置了。這套方案的核心在于理解Vite的構(gòu)建時(shí)替換機(jī)制并利用它來規(guī)避UniApp多端運(yùn)行時(shí)環(huán)境的差異。記住好的配置管理是項(xiàng)目工程化的基石花時(shí)間把它搭建穩(wěn)健能為后續(xù)的開發(fā)、測試和部署省去無數(shù)麻煩。如果在實(shí)踐中遇到新的問題不妨回頭檢查一下構(gòu)建產(chǎn)物的代碼看看變量是否被正確替換這往往是定位問題的捷徑。