動態

詳情 返回 返回

npm workspaces 已經夠強了,為何還需要 MonoRepo 方案? - 動態 詳情

隨着項目規模的增長和模塊化需求的增強,MonoRepo(單一代碼庫)的管理方式正在成為熱門選擇。本文將帶領你瞭解 MonoRepo 的形成背景,探討主流解決方案(如 pnpm workspaces、TurboRepo、Nx 和 Rush),並通過對比分析這些工具的優劣與適用場景,最終幫助你選擇最適合的工具。

MonoRepo 的形成背景

隨着項目複雜度和團隊規模的擴大,傳統的單體代碼庫或多代碼庫(PolyRepo)模式逐漸暴露出以下問題:

  • 依賴管理複雜: 各項目間共享依賴需要人工管理,更新成本高且容易出錯。
  • 重複代碼和資源浪費: 各項目可能重複實現相同功能,導致資源浪費和維護困難。
  • 協作效率低: 跨團隊協作難以同步進度,各自為政造成溝通和交付的瓶頸。

為了解決這些痛點,MonoRepo 應運而生。它將多個相關項目放在一個代碼庫中,提供一致的依賴管理和工具支持,使團隊協作和代碼複用變得更加高效。

MonoRepo 的優點:

  1. 統一依賴管理: 共享依賴和工具鏈,避免重複安裝和版本衝突。
  2. 跨項目協作: 項目間可以方便地引用和測試,減少交付時間。
  3. 原子化更改: 單次提交可以跨多個模塊,確保更改的完整性和一致性。

然而,MonoRepo 也帶來了新的挑戰,比如如何高效地管理構建任務、優化性能、以及避免依賴關係複雜化。因此,適合 MonoRepo 的工具解決方案應運而生。

用一個場景來比對目前主流解決方案的差異

場景概述

假設我們有一個MonoRepo 工程。 整體工程結構如下。

my-monorepo/
├── package.json         # 根目錄
├── packages/
│   ├── lib-a/           # 公共庫,提供基礎功能
│   │   ├── src/
│   │   └── package.json
│   ├── app1/            # 應用1,依賴 lib-a
│   │   ├── src/
│   │   └── package.json
│   └── app2/            # 應用2,依賴 lib-a
│       ├── src/
│       └── package.json

如果,我們修改了 app1 和 app2 的依賴庫 lib-a 。 那麼,我們在運行 app1 或者 app2 的時候, 需要先運行 lib-a 在運行,具體工程。 如果,沒有變動,則直接運行app1 或 app2.

使用 PNPM workspaces

  1. 安裝依賴
pnpm install 

由於 pnpm 的特性, packages 下所有工程的共有依賴,通過符號鏈接鏈接到全局緩存。

  1. 運行構建任務
    pnpm recursive run build
  • 運行所有子項目的 build 腳本,但無法自動跳過未修改的模塊
  • 構建順序需人工保證正確,無法根據依賴關係自動調整。

優點:

簡單直接,適合小型項目。

使用全局緩存優化安裝速度和磁盤利用率。

子項目依賴不會污染其他項目。

缺點:

無法基於任務依賴關係優化執行順序或跳過未修改模塊。

只能適用於比較簡單,輕量級的項目。

使用 TurboRepo

TurboRepo 是由 Vercel 推出的現代化 MonoRepo 工具,專注於任務調度和構建優化。

  1. 配置工程

在項目根目錄創建 `turbo.json`:

{
  "pipeline": {
    "build": {
      "dependsOn": ["^build"],
      "outputs": ["dist/**"]
    }
  }
}
  1. 運行構建任務
turbo run build
  • TurboRepo 會自動分析依賴關係,確保 lib-a 構建在前。
  • 如果 lib-a 沒有修改,TurboRepo 會利用緩存跳過構建,直接運行 app1app2 的任務。

優點:

  • 自動依賴管理,任務按順序執行。
  • 支持結果緩存,大幅提升效率。

缺點:

  • 對大型項目的任務調度和可視化支持較弱。

使用 Nx 解決

Nx 是一款功能強大的 MonoRepo 工具,提供了任務調度、依賴分析和可視化支持。 前 MonoRepo 解決方案 lerna 的收購方。

安裝和初始化:

npx create-nx-workspace@latest my-monorepo

生成依賴圖:

nx graph

自動生成可視化依賴圖,展示 lib-a 和應用之間的關係。

運行構建任務:

nx run-many --target=build --all
  • Nx 會根據依賴關係自動調整執行順序。
  • 支持本地和分佈式緩存,跳過未修改的模塊任務。

優點:

  • 提供依賴可視化工具,任務管理更加直觀。
  • 分佈式緩存適合團隊協作。

缺點:

  • 配置稍顯複雜,對上手要求較高。

使用 Rush 解決

Rush 是 Microsoft 為企業級項目設計的 MonoRepo 工具,專注於複雜依賴和構建管理。

初始化項目:

# 在根目錄下, 執行 rush init 初始化
rush init

定義構建流程:

rush.json 中配置依賴和任務:

{
  "projects": [
    {
      "packageName": "lib-a",
      "projectFolder": "packages/lib-a"
    },
    {
      "packageName": "app1",
      "projectFolder": "packages/app1",
      "dependencies": ["lib-a"]
    },
    {
      "packageName": "app2",
      "projectFolder": "packages/app2",
      "dependencies": ["lib-a"]
    }
  ]
}

運行構建任務:

rush build
  • Rush 會嚴格按照依賴順序執行任務,避免構建出錯。
  • 內置支持結果緩存和高效的 CI/CD 集成。

優點:

  • 企業級功能強大,適合超大型團隊協作。

缺點:

  • 配置複雜,上手門檻高。

整體對比

工具 依賴分析 緩存支持 構建優化 配置難度 適用場景
pnpm workspaces 本地緩存 無依賴優化 簡單 小型項目
TurboRepo 自動 本地緩存 增量構建 簡單 中小型項目
Nx 強大 本地/分佈式緩存 可視化依賴分析 適中 中大型項目
Rush 強大 分佈式緩存 高效任務調度 較高 超大型項目,企業級團隊

總結

通過例子我們可以看出,不同的 MonoRepo 工具在依賴分析、任務調度和緩存支持上的能力差異顯著:

  1. 輕量化選擇:

    • pnpm workspaces 適合簡單項目和個人開發者,易於上手但功能有限。
  2. 構建速度優先:

    • TurboRepo 在任務緩存和增量構建方面表現出色,適合中小型項目。
  3. 團隊協作:

    • Nx 提供依賴圖和分佈式緩存功能,適合協作頻繁的中大型團隊。
  4. 企業級複雜場景:

    • Rush 是企業項目的最佳選擇,支持超大規模項目和嚴格的依賴管理。

最終,選擇工具時需要綜合考慮項目規模、團隊需求和未來擴展規劃,找到最適合的 MonoRepo 解決方案。希望本文的實例和對比能夠為你的選型提供啓發!

user avatar dingtongya 頭像 Leesz 頭像 haoqidewukong 頭像 zaotalk 頭像 smalike 頭像 linlinma 頭像 yinzhixiaxue 頭像 jingdongkeji 頭像 qingzhan 頭像 kobe_fans_zxc 頭像 dirackeeko 頭像 littlelyon 頭像
點贊 262 用戶, 點贊了這篇動態!
點贊

Add a new 評論

Some HTML is okay.