跳轉到內容

環境變數和模式

Vite 在特殊的 import.meta.env 物件上暴露環境變數。這些變數在開發環境中定義為全域性變數,並在構建時進行靜態替換,以實現有效的搖樹最佳化(tree-shaking)。

示例
js
if (import.meta.env.DEV) {
  // code inside here will be tree-shaken in production builds
  console.log('Dev mode')
}

內建常量

在任何情況下都可使用以下內建常量:

  • import.meta.env.MODE: {string} 應用執行的模式

  • import.meta.env.BASE_URL: {string} 部署應用時的基本 URL。它由 base 配置項決定。

  • import.meta.env.PROD: {boolean} 應用是否執行在生產環境(透過 NODE_ENV='production' 啟動開發伺服器,或執行由 NODE_ENV='production' 構建的應用)。

  • import.meta.env.DEV: {boolean} 應用是否執行在開發環境(始終與 import.meta.env.PROD 相反)。

  • import.meta.env.SSR: {boolean} 應用是否執行在 服務端

環境變數

Vite 會自動將環境變數暴露在 import.meta.env 物件中(均為字串)。

VITE_ 為字首的變數才會在 Vite 打包後的客戶端原始碼中暴露。為了防止意外洩露環境變數,請避免使用此以外的字首。例如,考慮以下情況:

.env
VITE_SOME_KEY=123
DB_PASSWORD=foobar

解析後的 VITE_SOME_KEY 的值 —— "123" —— 將被暴露給客戶端,但 DB_PASSWORD 不會被暴露。您可以透過在程式碼中新增以下內容來測試:

js
console.log(import.meta.env.VITE_SOME_KEY) // "123"
console.log(import.meta.env.DB_PASSWORD) // undefined

如果您想自定義環境變數的字首,請參考 envPrefix 選項。

環境變數解析

如上所示,VITE_SOME_KEY 本應為數字,但解析後返回的是字串。布林值環境變數同樣會發生這種情況。在程式碼中使用時,請務必將其轉換為所需的型別。

保護敏感資訊

VITE_* 變數不應包含 API 金鑰等敏感資訊。這些變數的值在構建時會被打包進原始碼中。對於生產環境部署,請考慮使用後端伺服器或無伺服器/邊緣函式來妥善保護機密。

.env 檔案

Vite 使用 dotenv環境變數目錄下的以下檔案中載入額外的環境變數:

.env                # loaded in all cases
.env.local          # loaded in all cases, ignored by git
.env.[mode]         # only loaded in specified mode
.env.[mode].local   # only loaded in specified mode, ignored by git

環境變數載入優先順序

特定模式的環境變數檔案(例如 .env.production)的優先順序高於通用檔案(例如 .env)。

除了特定模式的 .env.[mode] 檔案外,Vite 總是會載入 .env.env.local。在特定模式檔案中宣告的變數優先順序最高;如果變數僅定義在 .env.env.local 中,它們在環境中依然可用。

此外,在 Vite 執行時已存在的環境變數擁有最高優先順序,不會被 .env 檔案覆蓋。例如,當執行 VITE_SOME_KEY=123 vite build 時。

.env 檔案在 Vite 啟動時載入。更改後請重啟伺服器。

Bun 使用者

使用 Bun 時請注意,Bun 會在指令碼執行前自動載入 .env 檔案。這種內建行為會將環境變數直接載入到 process.env 中,可能會干擾 Vite 的功能(因為 Vite 遵循現有的 process.env 值)。請參閱 oven-sh/bun#5515 獲取解決方案。

此外,Vite 開箱即用地使用 dotenv-expand 來展開環境變數。要了解更多語法資訊,請檢視其文件

注意,如果您想在環境變數值中使用 $,必須使用 \ 對其進行轉義。

.env
KEY=123
NEW_KEY1=test$foo   # test
NEW_KEY2=test\$foo  # test$foo
NEW_KEY3=test$KEY   # test123
反向順序展開變數

Vite 支援反向順序展開變數。例如,下方的 .env 將被解析為 VITE_FOO=foobarVITE_BAR=bar

.env
VITE_FOO=foo${VITE_BAR}
VITE_BAR=bar

這種行為在 shell 指令碼或其他工具(如 docker compose)中並不適用。但由於 dotenv-expand 長期支援此行為,且 JavaScript 生態系統中的其他工具通常使用支援此行為的舊版本,因此 Vite 也予以支援。

為避免互操作性問題,建議不要依賴此行為。Vite 未來可能會針對此行為發出警告。

忽略本地 .env 檔案

.env.*.local 檔案僅供本地使用,可能包含敏感變數。你應該在 .gitignore 中新增 *.local,以避免將其提交到 git 中。

TypeScript 的智慧感知(IntelliSense)

預設情況下,Vite 在 vite/client.d.ts 中為 import.meta.env 提供了型別定義。雖然您可以在 .env.[mode] 檔案中定義更多自定義環境變數,但您可能希望為以 VITE_ 開頭的自定義環境變數獲得 TypeScript 的智慧感知。

為此,您可以在 src 目錄下建立一個 vite-env.d.ts 檔案,並按如下方式擴充 ImportMetaEnv

vite-env.d.ts
typescript
interface ViteTypeOptions {
  // By adding this line, you can make the type of ImportMetaEnv strict
  // to disallow unknown keys.
  // strictImportMetaEnv: unknown
}

interface ImportMetaEnv {
  readonly VITE_APP_TITLE: string
  // more env variables...
}

interface ImportMeta {
  readonly env: ImportMetaEnv
}

如果您的程式碼依賴於瀏覽器環境的型別(如 DOMWebWorker),您可以更新 tsconfig.json 中的 lib 欄位。

tsconfig.json
json
{
  "lib": ["WebWorker"]
}

匯入會破壞型別擴充

如果 ImportMetaEnv 的型別擴充無效,請確保 vite-env.d.ts 中沒有任何 import 語句。有關詳細資訊,請參閱 TypeScript 文件

HTML 常量替換

Vite 還支援在 HTML 檔案中替換常量。import.meta.env 中的任何屬性都可以使用 %CONST_NAME% 語法在 HTML 檔案中使用:

html
<h1>Vite is running in %MODE%</h1>
<p>Using data from %VITE_API_URL%</p>

如果環境變數在 import.meta.env 中不存在(例如 %NON_EXISTENT%),它將被忽略且不會被替換,這與 JS 中 import.meta.env.NON_EXISTENT 被替換為 undefined 的行為不同。

鑑於 Vite 被許多框架使用,它特意不對複雜的替換(如條件判斷)進行預設。Vite 可以透過現有的使用者外掛或實現 transformIndexHtml 鉤子的自定義外掛進行擴充套件。

模式

預設情況下,開發伺服器(dev 命令)執行在 development 模式,而 build 命令執行在 production 模式。

這意味著當執行 vite build 時,它會從 .env.production(如果存在)中載入環境變數:

.env.production
VITE_APP_TITLE=My App

在應用中,您可以使用 import.meta.env.VITE_APP_TITLE 渲染標題。

在某些情況下,您可能希望以不同的模式執行 vite build 來渲染不同的標題。您可以透過傳遞 --mode 選項標誌來覆蓋命令使用的預設模式。例如,如果您想為 staging(預釋出)模式構建應用:

bash
vite build --mode staging

並建立一個 .env.staging 檔案:

.env.staging
VITE_APP_TITLE=My App (staging)

由於 vite build 預設執行生產構建,您也可以透過更改模式和 .env 檔案配置來執行開發構建:

.env.testing
NODE_ENV=development

NODE_ENV 和模式

需要注意的是,NODE_ENV (process.env.NODE_ENV) 和模式是兩個不同的概念。以下是不同命令如何影響 NODE_ENV 和模式:

命令NODE_ENV模式
vite build"production""production"
vite build --mode development"production""development"
NODE_ENV=development vite build"development""production"
NODE_ENV=development vite build --mode development"development""development"

NODE_ENV 和模式的不同值也反映在相應的 import.meta.env 屬性上:

命令import.meta.env.PRODimport.meta.env.DEV
NODE_ENV=productiontruefalse
NODE_ENV=developmentfalsetrue
NODE_ENV=otherfalsetrue
命令import.meta.env.MODE
--mode production"production"
--mode development"development"
--mode staging"staging"

.env 檔案中的 NODE_ENV

NODE_ENV=... 可以在命令中設定,也可以在 .env 檔案中設定。如果 NODE_ENV.env.[mode] 檔案中指定,則可以使用模式來控制其值。然而,NODE_ENV 和模式仍然是兩個不同的概念。

在命令中使用 NODE_ENV=... 的主要好處是讓 Vite 可以提前檢測到該值。它還允許您在 Vite 配置中讀取 process.env.NODE_ENV,因為 Vite 只能在配置求值後才能載入環境變數檔案。