Skip to content

Vite 環境變數管理:如何優雅地切換開發與生產環境?

Vite 環境變數:.env 檔案與 loadEnv

在前端開發中,我們經常需要根據不同環境,例如:開發、測試、生產,使用不同的 API 或金鑰。在 Vite 專案中,mode 參數與 .env 檔案是管理這些行為的核心。

最典型的用途就是 Axios 的 baseURL:把網址交給環境變數決定,程式碼就再也不用為了切換測試機與正式機而修改。

認識 Vite 的預設模式 (Mode)

vite.config.js 配置中,mode 參數表示當前的建構模式,它決定了應用程式的運行環境和行為。可以透過 mode 參數判斷目前的執行環境。

  • development:開發模式,執行 vitevite dev 時觸發。
  • production:生產模式,執行 vite build 時觸發。
js
export default defineConfig(({ mode }) => {
  // 透過 mode 可以得知目前是 'development' 還是 'production'
  console.log(mode);

  return {
    // 相關配置...
  };
});

mode 並不限於這兩個值,它可以是 任何字串。只要建立對應的 .env.[mode] 檔案,再用 --mode 指定即可,這也是專案能有測試機、預備機等多套設定的原因。

環境檔 .env 的建立與載入順序

Vite 會自動根據目前的模式載入對應的環境檔,建議將這些檔案放在專案的 根目錄 下。

檔案載入時機與說明
.env所有環境都會優先載入,存放共用變數。
.env.developmentnpm run dev 時使用。
.env.productionnpm run build 時使用。
.env.[mode]載入特定的環境變數時使用

同名變數會 由優先度高的覆蓋低的,順序如下(越後面越大):

  1. .env
  2. .env.local
  3. .env.[mode]
  4. .env.[mode].local

.local 結尾的檔案是給自己用的

.env.local.env.[mode].local 預設會被 git 忽略,適合放 只有你本機需要的覆寫,例如:指向自己電腦上的後端服務。這樣既不會影響同事,也不會把個人設定推上遠端。

命名規範:VITE_ 前綴

為了防止環境變數意外洩露給客戶端,Vite 規定只有以 VITE_ 開頭的變數才會被暴露給您的程式碼。

ini
VITE_API_URL = https://api.example.com
VITE_APP_NAME = MyApp

在程式碼中透過 import.meta.env 讀取:

js
const apiUrl = import.meta.env.VITE_API_URL;

加上前綴不等於安全,而是同意公開

VITE_ 的意思是 願意把這個值打包進前端檔案,任何人打開瀏覽器都看得到。私鑰、資料庫密碼、第三方服務的 secret 一律不能加前綴,也不該出現在前端專案裡。

改了沒生效?先檢查這三件事

  1. 變數是否忘了加 VITE_ 前綴。
  2. 修改 .env 後是否 重新啟動開發伺服器,這類檔案不會熱更新。
  3. 是否被優先度更高的 .env.local 蓋掉了。

另外 import.meta.env.XXX 是在 建置時被替換成字串,所以不能用變數動態組合屬性名稱去取值。

腳本讀取對應的環境變數

利用 --mode 切換不同的 .env 檔案。

json
{
  "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

js
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 手動載入。

延伸閱讀