儲存庫
文件
核心概念
快取工作

快取工作

每個 JavaScript 或 TypeScript 程式碼庫都需要執行 package.json 指令碼,例如 buildtestlint。在 Turborepo 中,我們稱這些為任務

Turborepo 可以快取您的任務結果和記錄,從而大幅提升執行速度緩慢的任務。

遺失快取

程式碼庫中的每個任務都有輸入輸出

  • build 任務可能以原始檔作為輸入,並將記錄輸出到 stderrstdout,以及已套件化的檔案。
  • linttest 任務可能以原始檔作為輸入,並將記錄輸出到 stdoutstderr

假設您使用 turbo run build 透過 Turborepo 執行 build 任務

  1. Turborepo 將評估您的任務輸入將它們轉換為雜湊(例如 78awdk123)。

  2. 檢查本機檔案系統快取,尋找相符的快取人工製品(例如 ./node_modules/.cache/turbo/78awdk123.tar.zst)。

  3. 如果 Turborepo 找不到任何與計算雜湊相符的人工製品,Turborepo 將會執行任務

  4. 任務成功完成後,Turborepo 會將所有指定的輸出(包括檔案和記錄)儲存到新的快取人工製品中,並以雜湊為地址。

Turborepo 在建立雜湊時會考量許多資訊:相依性圖、它所依賴的任務、原始檔、環境變數等等!

命中快取

假設您再次執行任務,但未變更任何輸入

  1. 雜湊將保持相同,因為輸入未變更(例如 78awdk123

  2. Turborepo 將找到具有相符雜湊的快取人工製品(例如 ./node_modules/.cache/turbo/78awdk123.tar.zst

  3. Turborepo 會重播輸出,而不是執行任務,將儲存的記錄列印到 stdout,並將儲存的輸出檔案還原到檔案系統中它們各自的位置。

從快取還原檔案和記錄幾乎是瞬間完成的。這可以將您的建置時間從數分鐘或數小時縮短到數秒或毫秒。雖然具體結果會根據程式碼庫相依性圖的形狀和粒度而有所不同,但大多數團隊發現,他們可以透過 Turborepo 的快取將整體每月建置時間減少約 40-85%。

關閉快取

在某些環境中,您不希望寫入快取輸出。若要停用快取寫入,請將 --no-cache 附加至任何指令。例如,這將執行 dev(以及所有它 dependsOn)在所有工作空間中,但它不會快取輸出

turbo run dev --no-cache

請注意,--no-cache 會停用快取寫入,但不會停用快取讀取。如果您要停用快取讀取,請使用 --force 標誌。

您也可以透過設定 pipeline.<task>.cache 設定檔為 false 來設定特定任務跳過寫入快取

{
  "$schema": "https://turbo.dev.org.tw/schema.json",
  "pipeline": {
    "dev": {
      "cache": false,
      "persistent": true
    }
  }
}

強制覆寫快取

相反地,如果您要停用讀取快取並強制 turbo 重新執行先前快取的任務,請加入 --force 標誌

# Run `build` npm script in all workspaces ignoring the cache.
turbo run build --force

請注意,--force 會停用快取讀取,但不會停用快取寫入。如果您要停用快取寫入,請使用 --no-cache 標誌。

處理 Node.js 版本

若要考量 Node.js 版本,請使用 package.json 中的 engines。Turborepo 會看到 package.json 的變更,並在更新欄位時錯失快取。

處理平台和其他任意雜湊貢獻者

對於進階使用案例,您可能希望作業系統 (OS)、架構或其他外部因素貢獻到您的雜湊。您可以透過四個快速步驟來執行此操作。

1. 將任意檔案寫入磁碟

首先,建立一個腳本來考量您有興趣的雜湊貢獻者。例如,以下是一個 Node.js 腳本,它會查看平台和架構,並將這些詳細資料寫入檔案 (turbo-cache-key.json)

#!/usr/bin/env node
 
const { writeFileSync } = require('fs');
const { join } = require('path');
 
const { platform, arch } = process;
const file = "turbo-cache-key.json";
const str = JSON.stringify({ platform, arch });
console.log(`Generating cache key: ${str}`);
writeFileSync(file, str);

2. 將檔案新增到您的 .gitignore

您不會想要將此檔案提交到原始碼控制,因為它依賴於環境。將它新增到您的 .gitignore

// .gitignore

+ turbo-cache-key.json

3. 將檔案新增到雜湊

現在,請確定 turbo 認識此檔案,方法是將它新增到任務輸入。您可以透過兩種方式執行此操作

{
  "$schema": "https://turbo.dev.org.tw/schema.json",
  "pipelines": {
    "build-for-platforms": {
      "dependsOn": ["^build"],
      "inputs": ["$TURBO_DEFAULT$", "turbo-cache-key.json"]
    }
  }
}
{
  "$schema": "https://turbo.dev.org.tw/schema.json",
  "globalDependencies": ["turbo-cache-key.json"],
  "pipelines": {
    ...
  }
}

4. 在執行 turbo 之前產生檔案

最後,您會希望在執行 turbo 之前執行指令碼。例如

{
  "scripts": {
    "build-for-platforms": "node ./scripts/create-turbo-cache-key.js && turbo run build"
  }
}

turbo run build 現在會在計算 build 任務的雜湊時,考量 turbo-cache-key.json 的內容。

記錄

turbo 不僅快取您任務的輸出,它還會將終端機輸出(即合併的 stdoutstderr)記錄到 (<package>/.turbo/run-<command>.log)。當 turbo 遇到快取任務時,它會重播輸出,就像它再次發生一樣,但會立即發生,且套件名稱會略微變暗。

雜湊

到目前為止,您可能想知道 turbo 如何決定特定任務的快取命中與否。好問題!

首先,turbo 會建構程式碼庫當前全域狀態的雜湊。這包括以下事項

  • 符合 globalDependencies 中 glob 模式的任何檔案內容雜湊
  • 列在 globalEnv 中的環境變數值
  • turbo.jsonpackage.json 和任何鎖定檔中選取資訊
  • 還有更多!

然後它會加入更多與特定工作區任務相關的因素

  • 工作區資料夾中所有版本控制檔案內容的雜湊值(或與 inputs 全域比對,如果已設定)相符的檔案
  • pipeline 中指定的已設定 outputs
  • 所有已安裝 dependenciesdevDependenciesoptionalDependencies 的已解析版本組
  • 工作區任務的名稱
  • pipeline.<task>.env 清單中指定的已排序環境變數金鑰值配對清單。
  • 還有更多!

一旦 turbo 在執行過程中遇到特定工作區的任務,它會檢查快取(本地和遠端)以尋找相符的雜湊值。如果相符,它會略過執行該任務,將快取的輸出移至或下載至適當位置,並立即重播先前記錄的記錄。如果快取中(無論是本地或遠端)沒有任何與計算出的雜湊值相符的項目,turbo 會在本地執行任務,然後快取指定的 輸出

在執行時間,特定任務的雜湊值會以環境變數 TURBO_HASH 提供給任務。此值可用於蓋印輸出或標記 Dockerfile 等。