Vite 環境變數管理:如何優雅地切換開發與生產環境?
在前端開發中,我們經常需要根據不同環境,例如:開發、測試、生產,使用不同的 API 或金鑰。在 Vite 專案中,mode 參數與 .env 檔案是管理這些行為的核心。
最典型的用途就是 Axios 的 baseURL:把網址交給環境變數決定,程式碼就再也不用為了切換測試機與正式機而修改。
認識 Vite 的預設模式 (Mode)
在 vite.config.js 配置中,mode 參數表示當前的建構模式,它決定了應用程式的運行環境和行為。可以透過 mode 參數判斷目前的執行環境。
- development:開發模式,執行
vite或vite dev時觸發。 - production:生產模式,執行
vite build時觸發。
export default defineConfig(({ mode }) => {
// 透過 mode 可以得知目前是 'development' 還是 'production'
console.log(mode);
return {
// 相關配置...
};
});mode 並不限於這兩個值,它可以是 任何字串。只要建立對應的 .env.[mode] 檔案,再用 --mode 指定即可,這也是專案能有測試機、預備機等多套設定的原因。
環境檔 .env 的建立與載入順序
Vite 會自動根據目前的模式載入對應的環境檔,建議將這些檔案放在專案的 根目錄 下。
| 檔案 | 載入時機與說明 |
|---|---|
.env | 所有環境都會優先載入,存放共用變數。 |
.env.development | npm run dev 時使用。 |
.env.production | npm run build 時使用。 |
.env.[mode] | 載入特定的環境變數時使用 |
同名變數會 由優先度高的覆蓋低的,順序如下(越後面越大):
.env.env.local.env.[mode].env.[mode].local
.local 結尾的檔案是給自己用的
.env.local 與 .env.[mode].local 預設會被 git 忽略,適合放 只有你本機需要的覆寫,例如:指向自己電腦上的後端服務。這樣既不會影響同事,也不會把個人設定推上遠端。
命名規範:VITE_ 前綴
為了防止環境變數意外洩露給客戶端,Vite 規定只有以 VITE_ 開頭的變數才會被暴露給您的程式碼。
VITE_API_URL = https://api.example.com
VITE_APP_NAME = MyApp在程式碼中透過 import.meta.env 讀取:
const apiUrl = import.meta.env.VITE_API_URL;加上前綴不等於安全,而是同意公開
VITE_ 的意思是 願意把這個值打包進前端檔案,任何人打開瀏覽器都看得到。私鑰、資料庫密碼、第三方服務的 secret 一律不能加前綴,也不該出現在前端專案裡。
改了沒生效?先檢查這三件事
- 變數是否忘了加
VITE_前綴。 - 修改
.env後是否 重新啟動開發伺服器,這類檔案不會熱更新。 - 是否被優先度更高的
.env.local蓋掉了。
另外 import.meta.env.XXX 是在 建置時被替換成字串,所以不能用變數動態組合屬性名稱去取值。
腳本讀取對應的環境變數
利用 --mode 切換不同的 .env 檔案。
{
"scripts": {
"dev": "vite",
"dev:development": "vite --mode development", // "dev"
"dev:test": "vite --mode test",
"dev:staging": "vite --mode staging",
"dev:production": "vite --mode production",
"build": "vite build",
"build:development": "vite build --mode development",
"build:test": "vite build --mode test",
"build:staging": "vite build --mode staging",
"build:production": "vite build --mode production" // 同 "build"
}
}這些指令都是靠 npm scripts 執行的,因此團隊只要記住 npm run build:test 這類名稱,不需要記得背後的參數。
進階技巧:在配置中使用 loadEnv
有時候我們需要在 vite.config.js 內部就先讀取到環境變數,例如:根據環境設定不同的 Proxy 代理,這時就需要用到 loadEnv。
import { defineConfig, loadEnv } from 'vite';
export default defineConfig(({ mode }) => {
// 手動載入環境變數
const env = loadEnv(mode, process.cwd(), '');
console.log(env);
return {
// 您的配置...
};
});原因是 vite.config.js 執行的時機 早於應用程式本身,此時還沒有 import.meta.env 可用,必須自己把 env 檔讀進來。
loadEnv 參數詳解
mode:Vite 目前的執行模式。它決定了要去找哪個.env.[mode]檔案。process.cwd():代表目前專案的根目錄路徑,告訴 Vite 到哪裡尋找環境檔。''(前綴字):這是過濾條件。預設 Vite 只會加載VITE_開頭的變數。如果您傳入空字串'',則會載入該環境檔中的所有變數。
常見問題:解決 ESLint 報錯
在 vite.config.js 中使用 process.cwd() 時,可能會遇到 no-undef 的 ESLint 警告。您可以選擇以下任一方式解決:
- 該行程式碼上方加上
// eslint-disable-next-line no-undef。 - 該檔案的第一行加上
/* eslint-disable no-undef */。 - 該檔案的第一行加上
/* global process */。 - 在
ESLint配置中設定環境:js{ env: { node: true; } }
結語
精確管理環境變數是確保應用程式安全與穩定的關鍵。透過 Vite 內建的 mode 機制搭配 .env 檔案,您可以輕鬆實現 一套程式碼,多環境運行 。別忘了,敏感資料(如私鑰)千萬不要加上 VITE_ 前綴,以確保它們只留在伺服器端!
常見問題
為什麼環境變數改了卻沒有生效?
最常見的三個原因:變數沒有 VITE_ 前綴、修改 .env 後沒有重新啟動開發伺服器、或是同名變數被優先度更高的 .env.local 覆蓋。
在程式碼中要怎麼讀取環境變數?
使用 import.meta.env.VITE_API_URL。Vite 在建置時會把它替換成實際的字串,因此不能用變數動態組合屬性名稱去取值。
VITE_ 前綴的變數安全嗎?
不安全。加上前綴等於同意把它打包進前端檔案,任何人都能在瀏覽器中看到。私鑰與後端憑證絕對不能加前綴,也不該放在前端專案裡。
.env.local 該用在什麼情況?
放個人本機才需要的覆寫設定,例如:指向自己電腦的後端網址。它預設會被 git 忽略,因此不會影響其他同事,優先度也高於同名的一般 env 檔。
自訂的 mode 需要另外設定嗎?
不需要額外設定,mode 可以是任何字串。只要建立對應的 .env.[mode] 檔案,再用 --mode 指定,Vite 就會載入它。
什麼時候才需要用 loadEnv?
當你要在 vite.config.js 本身用到環境變數時,例如:依環境設定 proxy 或 base 路徑。因為設定檔執行時 import.meta.env 還不存在,必須用 loadEnv 手動載入。