在 turbo.json
中設定 outputs
鍵,指明 Turborepo 在任務成功完成後應該緩存哪些文件或目錄。如果不設定這個鍵,Turborepo 將不會緩存任何文件,這意味著在後續運行中無法恢復任何文件輸出。
以下是一些常見工具的輸出設定範例:
.next
目錄中的所有內容,但排除 .next/cache
目錄。dist
或 build
目錄。{
"tasks": {
"build": {
"outputs": [".next/**", "!.next/cache/**"]
}
}
}
更多關於使用通配符(globbing patterns)設定 outputs
的信息,可以查看 globbing 規範文檔。
inputs
鍵用於指定希望包括在任務的哈希中用於緩存的文件。默認情況下,Turborepo 會包括套件中所有被 Git 跟踪的文件。然而,您可以使用 inputs
鍵更具體地指定哈希中包含的文件。
例如,一個用於檢查 Markdown 文件中的錯別字的任務可以這樣定義:
{
"tasks": {
"spell-check": {
"inputs": ["**/*.md", "**/*.mdx"]
}
}
}
如此設定後,只有 Markdown 文件的變更會導致 spell-check
任務的緩存失效。
這個功能讓你完全不使用 Turborepo 默認的輸入行為,也就是說你的 .gitignore
文件將不再被尊重,你需要確保不要用你的通配符匹配到這些文件。
如果想恢復默認行為,可以使用 $TURBO_DEFAULT$
微語法。
通常,你會希望對任務使用默認的輸入行為。但是,你可以通過微調輸入來提高特定任務的緩存命中率,忽略已知不影響任務輸出的文件變更。
例如,下面的任務定義中,Turborepo 將使用構建任務的默認輸入行為,但會忽略 README.md
文件的變更。如果 README.md
文件發生變更,任務仍然會命中緩存:
{
"tasks": {
"build": {
"inputs": ["$TURBO_DEFAULT$", "!README.md"]
}
}
}
這些設定有助於你更有效地利用 Turborepo 的高級功能,如緩存、並行處理和工作流管理,從而提高開發效率和專案管理的靈活性。
你可以在工作空間的根目錄中使用 turbo
命令執行 package.json
中的腳本。例如,除了在每個套件中執行 lint
任務外,你還可能想在工作空間的根目錄執行一個名為 lint:root
的任務:
{
"tasks": {
"lint": {
"dependsOn": ["^lint"]
},
"#lint:root": {}
}
}
套件配置是放置在套件內部的 turbo.json
文件。這允許套件定義自己任務的特定行為,而不影響其餘的倉庫。
在大型單一倉庫(monorepo)與多團隊協作的環境中,這使得各個團隊可以更好地控制自己的任務。要了解更多信息,可以訪問套件配置的文檔。
有些任務應該無論如何都要運行,比如在緩存構建後的部署腳本。對於這些任務,可以在任務定義中添加 "cache": false
:
{
"tasks": {
"deploy": {
"dependsOn": ["^build"],
"cache": false},
"build": {
"outputs": ["dist/**"]
}
}
}
有些任務即使依賴其他套件也可以並行運行。一個典型的例子是代碼檢查器,因為檢查器不需要等待依賴的輸出就能成功運行。
由於這個原因,你可能會誘惑定義你的 check-types
任務如下:
{
"tasks": {
"check-types": {} // 不正確!
}
這樣會讓你的任務並行運行 - 但沒有考慮到來源代碼的變更。這意味著你可以:
ui
套件中進行破壞性改變。turbo check-types
,在一個依賴 ui
的應用套件中命中緩存。因此,你需要對你的 check-types
任務定義做一個小改動:
{
"tasks": {
"check-types": {
"dependsOn": ["^check-types"] // 這樣可以運行...但可能更快!
}
}
如果你再次測試在你的 ui
套件中進行破壞性改變,你會注意到緩存行為現在是正確的。然而,任務不再並行運行了。
要同時滿足正確性和並行性的需求,你可以在任務圖中引入過渡節點(Transit Nodes):
{
"tasks": {
"transit": {
"dependsOn": ["^transit"]
},
"check-types": {
"dependsOn": ["transit"]
}
}
這些過渡節點利用一個不做任何事情的任務來創建你的套件依賴之間的關係,因為它不匹配任何 package.json
中的腳本。因此,你的任務可以並行運行,同時意識到它們內部依賴的變更。
在這個例子中,我們使用了 transit
作為任務名 - 但你可以用任何不是你工作空間中已有腳本的名稱。