儲存庫
文件
核心概念
環境變數輸入

環境變數輸入

由於環境變數並未擷取在原始碼中,因此無法輕鬆地在多部機器間共用。確保開發人員和 CI 在不同機器間設定一致的環境是一項困難的任務。Turborepo 提供工具,讓您可以表達應用程式所依賴的環境變數。

組態

Turborepo 讓您能夠直接列舉應考慮用於雜湊金鑰的環境變數,在全域層級和 管線 層級皆可。

{
  "$schema": "https://turbo.dev.org.tw/schema.json",
  "globalEnv": ["API_BASE_URL"],
  "pipeline": {
    "test": {
      "env": ["MOCHA_REPORTER"]
    },
    //...
  }
}

在此範例中,我們可以想像一個在測試環境、暫存環境和生產環境中具有不同 API_BASE_URL 的應用程式。此組態將確保 API_BASE_URL 的值會考慮用於雜湊,如果不同,則不會從快取中還原任務。

此外,我們可以看到 test 任務希望根據 MOCHA_REPORTER 的值採用不同的快取行為,這可以用於讓 CI 整合到與本地開發不同的服務。

globalEnv

包含在 globalEnv 金鑰中的環境變數會影響所有任務的雜湊。

pipeline.<task>.env

包含在 pipeline.<task>.env 中的環境變數只會影響該任務的雜湊。

萬用字元

turbo.json 中接受環境變數的每個地方都接受萬用字元,包括任務層級的 env 和全域層級的 globalEnv。這讓您可以輕鬆指定環境變數的樣式名稱,包括包含和排除

{
  "$schema": "https://turbo.dev.org.tw/schema.json",
  "pipeline": {
    "build": {
      "env": ["NEXT_PUBLIC_*", "!NEXT_PUBLIC_GIT_*"]
    }
  }
}

排除樣式僅適用於透過包含匹配的變數組。

小心使用萬用字元和 CI 環境的組合。有些 CI 環境會設定額外的環境變數,例如 NEXT_PUBLIC_VERCEL_GIT_COMMIT_SHA,這將永遠無法獲得快取命中。在設定萬用字元後,請務必仔細檢閱來自所有環境的 執行摘要,以確保它只包含您關心的變數。

語法

由於這些值是在 JSON 中指定的,而 JSON 使用 \ 作為跳脫字元,因此您需要確保傳入的值解析為跳脫字串。

  • 樣式中的任何 * 都會匹配零個或多個字元。
  • 開頭的 ! 表示整個樣式將會被否定。
  • 在第一個位置以外的任何位置的 ! 是字面上的 !
  • 具有特殊含義的字元(前導 !*)可以在它們前面放置 \ 來轉義,以取得字面值。

範例

  • "*":符合每個環境變數。
  • "!*":排除每個環境變數。
  • "FOO*":符合 FOOFOODFOO_FIGHTERS 等。
  • "FOO\*":因為這是在 JSON 中指定的,所以這會解析為 "FOO*",並符合 FOOFOODFOO_FIGHTERS
  • "FOO\\*":符合單一環境變數,名稱為 FOO*
  • "!FOO*":排除所有以 FOO 開頭的環境變數。
  • "\!FOO":因為這是在 JSON 中指定的,所以這會解析為 "!FOO",並從符合的集合中排除單一環境變數,名稱為 !FOO
  • "\\!FOO":符合單一環境變數,名稱為 !FOO
  • "FOO!":符合單一環境變數,名稱為 FOO!

寬鬆和嚴格環境模式

Turborepo 提供兩種不同的模式來處理任務中的環境變數:寬鬆模式和嚴格模式。該模式控制在執行時哪些環境變數可供每個任務使用。

寬鬆模式

寬鬆模式是預設行為,不會過濾任何環境變數。因此,機器中的所有環境變數都會提供給每個任務。這確保了最大的相容性,同時接受任務會隱式存取未指定環境變數的風險。使用者可能會使用不同環境變數值執行任務,但錯誤地看到 FULL TURBO,因為環境變數未在turbo.json中設定。

嚴格模式

嚴格模式,可以使用turbo --env-mode=strict啟用,會過濾環境變數。

只有重要的系統環境變數和在turbo.json中設定的環境變數會提供給任務。

如果要讓環境變數成為快取金鑰的一部分,請使用雜湊環境變數

如果您希望環境變數成為快取金鑰的一部分,請使用未雜湊環境變數

系統環境變數

即使在嚴格模式下,Turborepo 也會將下列環境變數傳遞給所有工作

  • PATH
  • SHELL
  • SYSTEMROOT

雜湊環境變數

globalEnvenv 中定義的雜湊環境變數將提供給工作,並包含在雜湊快取金鑰中。

例如 NODE_ENV 等環境變數,其值可能會變更工作輸出,應包含在 globalEnvenv 中。

未雜湊環境變數

globalPassThroughEnvpassThroughEnv 中定義的未雜湊環境變數將提供給工作,但不會包含在雜湊快取金鑰中。

例如 NPM_TOKEN 等會因使用者而異的存取權杖,但會產生相同的任務輸出,應定義在 globalPassThroughEnvpassThroughEnv 中。

推論模式

Turborepo 透過推斷您是否需要從組態中取得 strict 行為,以逐步採用嚴格模式。

  • "globalPassThroughEnv": []。嚴格模式已針對每個工作啟用。沒有環境變數被允許列入白名單。
  • "passThroughEnv": []。嚴格模式已針對特定工作啟用。沒有環境變數被允許列入白名單。

.env 檔案

Turborepo 沒有將 .env 檔案載入到環境中!您的工作必須自行處理載入 .env 檔案。

框架通常使用 dotenv(在新分頁中開啟) 自動為工作載入環境變數。這可能會讓 Turborepo 難以預設了解您的工作環境

  • .env 檔案將環境變數儲存在 檔案 中,而不是環境中。
  • 來自此檔案的環境變數會在 Turborepo 已開始執行工作 之後 載入。
  • 檔案通常會在 .gitignore 中指定,因此 Turborepo 預設不會將其包含在工作雜湊中。

由於僅使用檔案輸入來正確設定此設定的複雜性,Turborepo 明確支援 .env 檔案模式,使用 globalDotEnvdotEnv 欄位在 turbo.json 內部。若要讓 Turborepo 考量適當的 .env 檔案組,請在 turbo.json 內部指定它們。以下是 Next.js 應用程式的正確 dotEnv 設定

在大部分情況下,此設定應與您的架構行為相符,而不是您目前應用程式使用的特定設定。

{
  "$schema": "https://turbo.dev.org.tw/schema.json",
  "globalDotEnv": [".env"],
  "pipeline": {
    "build": {
      "dotEnv": [".env.production.local", ".env.local", ".env.production", ".env"]
    },
    "dev": {
      "dotEnv": [".env.development.local", ".env.local", ".env.development", ".env"]
    },
    "test": {
      "dotEnv": [".env.test.local", ".env.test", ".env"]
    }
  }
}

這些欄位是 Unix 格式 (/ 分隔) 路徑的已排序清單,相對於 globalDotEnv 的根目錄,相對於 dotEnv 的工作區。它們不支援萬用字元或絕對路徑。

架構推論

此功能可透過傳遞 --framework-inference=false 至您的 turbo 指令來停用。

預設情況下,Turborepo 會嘗試偵測 turborepo 內工作區的架構,並使用此偵測結果來協助確保所有預設環境變數都適當地考慮到工作任務雜湊。

如果 Turborepo 成功偵測到您的架構,您不需要在 turbo.json 的管道設定中手動指定特定架構特定的環境變數。Turborepo 會將支援的架構和外卡環境變數納入工作任務的 env 金鑰,如下所示:

架構env 外卡
AstroPUBLIC_*
BlitzNEXT_PUBLIC_*
建立 React 應用程式REACT_APP_*
GatsbyGATSBY_*
Next.jsNEXT_PUBLIC_*
Nuxt.jsNUXT_ENV_*
RedwoodJSREDWOOD_ENV_*
Sanity StudioSANITY_STUDIO_*
SolidVITE_*
SvelteKitVITE_*
ViteVITE_*
VueVUE_APP_*

您可以透過以下方式判斷 Turborepo 是否成功偵測到您工作區的架構:

  • 檢查執行摘要(透過 --summarize)。
  • 檢查乾運行輸出(透過 --dry)。

架構推論排除

Turborepo 從架構推論自動包含的萬用字元也可能與 CI 平台插入環境中的環境變數相符。這些變數可能包含執行 ID 或 Git SHA,如果包含在內,將保證永遠不會獲得快取命中。

因此,Turborepo 提供兩種方法從雜湊中排除變數

  1. 設定 TURBO_CI_VENDOR_ENV_KEY,並加上排除前綴。如果 CI 環境偵測到您正在使用 Turborepo,理想情況下會由 CI 環境為您處理。例如,對於在 Vercel 上建置的 Next.js 應用程式,Vercel 會設定 TURBO_CI_VENDOR_ENV_KEY=NEXT_PUBLIC_VERCEL_,以確保不包含會導致快取問題的變數。此變數僅針對推論的架構變數進行處理。

  2. 使用 "env": ["!NEXT_PUBLIC_UNNEEDED_*"] 在適當的 task 定義的 env 手動指定排除項。這能極為精細地控制環境變數排除,避免納入雜湊考量。

架構推論是針對每個工作區

環境變數僅會包含在使用該架構的工作區中任務的快取金鑰中。換句話說,為 Next.js 應用程式推論的環境變數僅會包含在偵測為 Next.js 應用程式的任務快取金鑰中。單一儲存庫中其他工作區的任務不會包含這些變數。

例如,此 turbo.json 指定兩個獨立工作區 (next-apputils) 的建置行為,僅會為 next-app 包含 NEXT_PUBLIC_*

{
  "$schema": "https://turbo.dev.org.tw/schema.json",
  "pipeline": {
    "next-app#build": {
      "outputs": [".next/**", "!.next/cache/**"]
    },
    "utils#build": {
      "outputs": ["dist/**"],
    },
  }
}

eslint-config-turbo

為進一步協助偵測潛入您的建置中未見的環境變數依賴項,並協助確保您的 Turborepo 快取在環境間正確共用,請使用 eslint-config-turbo(在新分頁中開啟) 套件。此 ESLint 設定檔將提供編寫時間回饋,針對 Turborepo 在 turbo.json 中偵測為未指定的環境變數使用情況。

若要開始,請在您的 eslintrc(在新分頁中開啟) 檔案中從 eslint-config-turbo 延伸。

{
  // Automatically flag env vars missing from turbo.json
  "extends": ["turbo"]
}

若要更進一步控制規則,您可以安裝並設定 eslint-plugin-turbo(在新分頁中開啟) 外掛程式,首先將其新增至外掛程式,然後設定所需的規則。

{
  "plugins": ["turbo"],
  "rules": {
    // Automatically flag env vars missing from turbo.json
    "turbo/no-undeclared-env-vars": "error"
  }
}

如果您在程式碼中使用未在 turbo.json 中宣告的非架構相關環境變數,外掛程式會發出警告。

隱形環境變數

由於 Turborepo 在您的工作之前執行,因此您的工作有可能在 turbo 已為特定工作計算雜湊後,建立或變更環境變數。例如,考慮這個 package.json

{
  "scripts": {
    "build": "source .env && next build"
  }
}
export NEXT_PUBLIC_GA_ID=UA-00000000-0

turbo,在執行 build 程式碼之前計算任務雜湊後,將不會發現 NEXT_PUBLIC_GA_ID 環境變數的值,因此無法根據其值分割快取。請務必確保在呼叫 turbo 之前,已將所有環境變數載入環境中!

{
  "$schema": "https://turborepo.org/schema.json",
  "pipeline": {
    "build": {
      "env": ["NEXT_PUBLIC_GA_ID"],
      "outputs": [".next/**", "!.next/cache/**"],
    },
  }
}