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