快取工作
每個 JavaScript 或 TypeScript 程式碼庫都需要執行 package.json
指令碼,例如 build
、test
和 lint
。在 Turborepo 中,我們稱這些為任務。
Turborepo 可以快取您的任務結果和記錄,從而大幅提升執行速度緩慢的任務。
遺失快取
程式碼庫中的每個任務都有輸入和輸出。
build
任務可能以原始檔作為輸入,並將記錄輸出到stderr
和stdout
,以及已套件化的檔案。lint
或test
任務可能以原始檔作為輸入,並將記錄輸出到stdout
和stderr
。
假設您使用 turbo run build
透過 Turborepo 執行 build
任務
-
Turborepo 將評估您的任務輸入並將它們轉換為雜湊(例如
78awdk123
)。 -
檢查本機檔案系統快取,尋找相符的快取人工製品(例如
./node_modules/.cache/turbo/78awdk123.tar.zst
)。 -
如果 Turborepo 找不到任何與計算雜湊相符的人工製品,Turborepo 將會執行任務。
-
任務成功完成後,Turborepo 會將所有指定的輸出(包括檔案和記錄)儲存到新的快取人工製品中,並以雜湊為地址。
Turborepo 在建立雜湊時會考量許多資訊:相依性圖、它所依賴的任務、原始檔、環境變數等等!
命中快取
假設您再次執行任務,但未變更任何輸入
-
雜湊將保持相同,因為輸入未變更(例如
78awdk123
) -
Turborepo 將找到具有相符雜湊的快取人工製品(例如
./node_modules/.cache/turbo/78awdk123.tar.zst
) -
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
認識此檔案,方法是將它新增到任務輸入。您可以透過兩種方式執行此操作
- 對於特定任務:將檔案包含在 任務的
inputs
陣列 中
{
"$schema": "https://turbo.dev.org.tw/schema.json",
"pipelines": {
"build-for-platforms": {
"dependsOn": ["^build"],
"inputs": ["$TURBO_DEFAULT$", "turbo-cache-key.json"]
}
}
}
- 針對所有任務:將檔案新增至
globalDependencies
{
"$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
不僅快取您任務的輸出,它還會將終端機輸出(即合併的 stdout
和 stderr
)記錄到 (<package>/.turbo/run-<command>.log
)。當 turbo
遇到快取任務時,它會重播輸出,就像它再次發生一樣,但會立即發生,且套件名稱會略微變暗。
雜湊
到目前為止,您可能想知道 turbo
如何決定特定任務的快取命中與否。好問題!
首先,turbo
會建構程式碼庫當前全域狀態的雜湊。這包括以下事項
- 符合
globalDependencies
中 glob 模式的任何檔案內容雜湊 - 列在
globalEnv
中的環境變數值 - 從
turbo.json
、package.json
和任何鎖定檔中選取資訊 - 還有更多!
然後它會加入更多與特定工作區任務相關的因素
- 工作區資料夾中所有版本控制檔案內容的雜湊值(或與
inputs
全域比對,如果已設定)相符的檔案 - 在
pipeline
中指定的已設定outputs
- 所有已安裝
dependencies
、devDependencies
和optionalDependencies
的已解析版本組 - 工作區任務的名稱
- 在
pipeline.<task>.env
清單中指定的已排序環境變數金鑰值配對清單。 - 還有更多!
一旦 turbo
在執行過程中遇到特定工作區的任務,它會檢查快取(本地和遠端)以尋找相符的雜湊值。如果相符,它會略過執行該任務,將快取的輸出移至或下載至適當位置,並立即重播先前記錄的記錄。如果快取中(無論是本地或遠端)沒有任何與計算出的雜湊值相符的項目,turbo
會在本地執行任務,然後快取指定的 輸出
。
在執行時間,特定任務的雜湊值會以環境變數 TURBO_HASH
提供給任務。此值可用於蓋印輸出或標記 Dockerfile 等。