Vite 環境變數 .env 怎麼設定:模式、優先順序與前端密鑰邊界
Vite 的 .env 最常見的誤解是「變數名稱加上 VITE_ 就算安全地設定完成」。事實正好相反:VITE_ 是要暴露給瀏覽器的明確標記,值會在建置時被替換進前端 bundle。因此公開 API base URL 可以放,token、資料庫密碼與第三方服務 secret 不可以。
直接答案是:前端可公開的設定才用 VITE_;真正的 secret 留在 server、部署平台或 CI 的 secrets。模式差異用 .env.[mode] 管理,並在 build 前檢查實際載入值。
基本檔案與命名規則
最小範例:
VITE_API_BASE_URL=https://api.example.comVITE_APP_NAME=Example前端程式以 import.meta.env 讀取:
const apiBaseUrl = import.meta.env.VITE_API_BASE_URL;Vite 預設只把 VITE_ 開頭的項目暴露到 client code,正是為了避免把所有 process environment 不小心打包進去。但它不是 secret 保護機制:一旦用此前綴,任何使用者都能從產物或瀏覽器開發工具取得該值。
mode 決定哪些檔案會載入
常見的檔案分工如下:
.env # 所有 mode 的共通非敏感設定.env.local # 本機覆寫,不提交 Git.env.production # production mode 設定.env.production.local # production 本機/CI 覆寫,不提交 Gitvite dev 預設使用 development mode,vite build 預設使用 production mode;可明確指定:
vite build --mode staging這會載入 .env、.env.local、.env.staging 與 .env.staging.local。若某個環境值只應存在於 staging,不要放在共通 .env 後再期待它被覆蓋,因為看設定檔的人很容易誤用。
優先順序:既有 environment 的優先權最高
Vite 不會覆蓋執行指令前就已存在的環境變數;這讓 CI 或平台注入的值優先於 .env。其後才是模式專屬檔與共通檔。實務上,不要把 .env 當成 production secret 的唯一來源:本機開發用 .env.local,正式值交給部署平台或 CI 的 secret store。
也要記得 Vite 會在啟動時載入 env。修改 .env 後,重啟 dev server;只重新整理瀏覽器通常看不到新值。
在 vite.config.ts 讀取變數時用 loadEnv
Vite 設定檔在處理時,不會自動把所有 .env 值放到 process.env。需要依 mode 設定 proxy 或 build 行為時,明確載入:
import { defineConfig, loadEnv } from 'vite';
export default defineConfig(({ mode }) => { const env = loadEnv(mode, process.cwd(), '');
return { server: { proxy: { '/api': { target: env.API_ORIGIN }, }, }, };});第三個參數設成空字串會載入所有 prefix,適合只在 server-side config 使用的 API_ORIGIN;不要因此把它改成 VITE_API_ORIGIN,除非瀏覽器也真的需要知道該值。
發布前五項檢查
VITE_項目是否都可以公開?.env.local與*.local是否已在.gitignore?- staging、production 是否使用明確的
--mode或部署環境設定? - 改
.env後是否重啟 Vite? - 是否在 build 產物或瀏覽器檢查過沒有意外出現 secret 名稱或值?
把 .env 視為建置輸入,而不是加密保險箱,就能避免最常見的 Vite 設定外洩。
常見問題
Q: 為什麼 import.meta.env.MY_SECRET 是 undefined?
A: 預設只有 VITE_ 開頭的變數會暴露給 client code。這是刻意的安全邊界;若它真的是 secret,應留在 server 或部署平台,而非改名前綴讓前端讀取。
Q: 可以把 private API key 放在 .env.local 嗎?
A: 可以作為本機 server-side 工具或後端的輸入,但不能在 client code 讀取,也不能使用 VITE_ 前綴。.env.local 不提交 Git 不代表送進前端 bundle 後仍是私密資訊。
參考資料:
回報錯字、失效連結,或告訴我你想看的延伸主題。