Turborepo 0.4.0
我很興奮地宣布 Turborepo v0.4.0 的發布!
- 速度提升 10 倍:
turbo
已從頭開始以 Go 語言重寫,使其速度更快 - 更聰明的雜湊:改良的雜湊演算法現在考慮已解析的依賴項,而不僅僅是整個根鎖定檔的內容
- 部分鎖定檔 / 稀疏安裝:生成根鎖定檔和 monorepo 的精簡子集,其中僅包含給定目標所需的套件
- 細緻的排程:透過
pipeline
配置改進任務協調和選項 - 更佳的快取控制:您現在可以針對每個任務指定快取輸出
以 Go 語言重寫
雖然我最初在 TypeScript 中建立了 turbo
的原型,但很明顯,路線圖上的某些項目需要更好的效能。經過大約一個月左右的工作,我很高興終於發布 Go 版本的 turbo
CLI。它不僅在毫秒內啟動,而且新的 Go 實作在雜湊處理速度上比 Node.js 實作快 10 到 100 倍。憑藉這個新的基礎(以及您即將讀到的一些功能),Turborepo 現在可以擴展到星系級大小的專案,同時保持極快的速度,這一切都歸功於 Go 出色的並發控制。
更佳的雜湊處理
v0.4.0 中的雜湊處理不僅更快,而且更聰明。
主要的變更是 turbo
不再在其雜湊器(負責判斷給定任務是否存在於快取中或是否需要執行的演算法)中包含根鎖定檔內容的雜湊值。相反,turbo
現在根據根鎖定檔雜湊套件的 dependencies
和 devDependencies
的已解析版本集合。
舊的行為會在根鎖定檔以任何方式變更時,使快取爆炸。透過這種新行為,變更鎖定檔只會使受新增/變更/移除依賴項影響的那些套件的快取失效。雖然這聽起來很複雜,但再次強調,這一切都表示,當您從 npm 安裝/移除/更新依賴項時,只有那些實際上受到變更影響的套件才需要重建。
實驗性功能:精簡工作區
我們最大的客戶痛點/請求之一是改進在使用大型 Yarn 工作區(或任何工作區實作)時的 Docker 建置時間。核心問題是工作區的最佳功能——將您的 monorepo 縮減為單一鎖定檔——在 Docker 層快取方面也是最糟糕的。
為了幫助闡明問題以及 turbo
現在如何解決它,讓我們看一個範例。
假設我們有一個使用 Yarn 工作區的 monorepo,其中包含一組名為 frontend
、admin
、ui
和 backend
的套件。我們也假設 frontend
和 admin
都是 Next.js 應用程式,它們都依賴相同的內部 React 元件庫套件 ui
。現在我們也假設 backend
包含一個 Express TypeScript REST API,它實際上並沒有與我們 monorepo 的任何其他部分共享太多程式碼。
以下是 frontend
Next.js 應用程式的 Dockerfile 可能看起來的樣子
雖然這可行,但有些事情可以做得更好
- 您手動
COPY
內部套件和建置目標應用程式所需的文件,並且需要記住哪些需要先建置。 - 您在 Dockerfile 中非常早期的位置
COPY
根yarn.lock
鎖定檔,但此鎖定檔是整個 monorepo 的鎖定檔。
當您的 monorepo 變得越來越大時,最後一個問題尤其令人痛苦,因為對此鎖定檔的任何變更都會觸發幾乎完整的重建,無論應用程式是否實際上受到新的/變更的依賴項的影響。
...直到現在。
透過全新的 turbo prune
命令,您現在可以透過確定性地為目標套件生成具有精簡鎖定檔的稀疏/部分 monorepo 來解決這個噩夢——而無需安裝您的 node_modules
。
讓我們看看如何在 Docker 內部使用 turbo prune
。
那麼 turbo prune
的輸出到底是什麼?一個名為 out
的資料夾,其中包含以下內容
- 一個
json
資料夾,其中包含精簡工作區的 package.jsons - 一個
full
資料夾,其中包含精簡工作區的完整原始碼,但僅包含建置目標所需的內部套件 - 一個新的精簡鎖定檔,其中僅包含原始根鎖定檔的精簡子集,以及精簡工作區中套件實際使用的依賴項。
由於上述原因,Docker 現在可以設定為僅在有真正理由時才重建每個應用程式。因此,frontend
僅在其原始碼或依賴項(內部或來自 npm)實際變更時才會重建。admin
和 backend
也是如此。對 ui
的變更(無論是對其原始碼或依賴項的變更)都會觸發 frontend
和 admin
的重建,但不會觸發 backend
的重建。
雖然這個範例看起來很簡單,但試想一下,如果每個應用程式都需要長達 20 分鐘才能建置和部署。這些節省真的開始快速累積,尤其是在大型團隊中。
Pipeline
為了讓您更進一步控制您的 Turborepo,我們在 turbo
的配置中新增了 pipeline
。pipeline
中的這個新欄位可讓您指定 monorepo 中 npm 指令碼之間的關聯方式,以及一些額外的每個任務選項。然後 turbo
使用此資訊來最佳化排程 monorepo 中的任務,從而消除原本會存在的瀑布。
以下是它的運作方式
上述配置然後將由 turbo
解釋,以最佳化排程執行。
這實際上是什麼意思?在過去(例如 Lerna 和 Nx),turbo
只能以拓樸順序執行任務。透過新增 pipeline,turbo
現在除了實際的依賴圖之外,還建構了一個拓樸「動作」圖,它使用該圖來判斷應以最大並發性執行的任務順序。最終結果是您不再浪費閒置的 CPU 時間等待事物完成(即,不再有瀑布)。
改進的快取控制
由於 pipeline
,我們現在有一個很好的位置可以針對每個任務開啟 turbo
的快取行為。
以上述範例為基礎,您現在可以像這樣在整個 monorepo 中設定快取輸出慣例
注意:目前,pipeline
存在於專案層級,但在後續版本中,這些將可在每個套件的基礎上覆寫。
下一步是什麼?
我知道這很多,但還有更多內容即將推出。以下是 Turborepo 路線圖上的下一步。
- 一個登陸頁面!
- 使用
@turborepo/server
的遠端快取 - 建置掃描、遙測和指標以及依賴項和任務圖視覺化
- 桌面主控台 UI
- 智慧型
watch
模式 - 適用於 TypeScript、React、Jest、Node.js、Docker、Kubernetes 等的官方建置規則
致謝
- Iheanyi Ekechukwu,感謝他指導我了解 Go 生態系統
- Miguel Oller 和 Makeswift 團隊,感謝他們反覆運算新的
prune
命令