Skip to content

Bun 中的目錄(Catalogs)提供了一種簡單的方法,在 monorepo 中的多個包之間共享通用依賴版本。與其在每個工作區包中重復指定相同的版本,不如在根 package.json 中一次性定義它們,並在整個項目中一致地引用它們。

概述

與傳統的依賴管理不同(每個工作區包需要獨立指定版本),目錄讓你可以:

  1. 在根 package.json 中定義版本目錄
  2. 使用簡單的 catalog: 協議引用這些版本
  3. 只需在一個地方更改版本,即可同時更新所有包

這在大型 monorepo 中特別有用,其中數十個包需要使用相同版本的關鍵依賴。

如何使用目錄

目錄結構示例

考慮一個具有以下結構的 monorepo:

my-monorepo/
├── package.json
├── bun.lock
└── packages/
    ├── app/
    │   └── package.json
    ├── ui/
    │   └── package.json
    └── utils/
        └── package.json

1. 在根 package.json 中定義目錄

在根級別的 package.json 中,在 workspaces 對象內添加 catalogcatalogs 字段:

json
{
  "name": "my-monorepo",
  "workspaces": {
    "packages": ["packages/*"],
    "catalog": {
      "react": "^19.0.0",
      "react-dom": "^19.0.0"
    },
    "catalogs": {
      "testing": {
        "jest": "30.0.0",
        "testing-library": "14.0.0"
      }
    }
  }
}

如果你將 catalogcatalogs 放在 package.json 文件的頂層,也可以正常工作。

2. 在工作區包中引用目錄版本

在工作區包中,使用 catalog: 協議引用版本:

json
{
  "name": "app",
  "dependencies": {
    "react": "catalog:",
    "react-dom": "catalog:",
    "jest": "catalog:testing"
  }
}
json
{
  "name": "ui",
  "dependencies": {
    "react": "catalog:",
    "react-dom": "catalog:"
  },
  "devDependencies": {
    "jest": "catalog:testing",
    "testing-library": "catalog:testing"
  }
}

3. 運行 Bun Install

運行 bun install 以根據目錄版本安裝所有依賴。

Catalog 與 Catalogs

Bun 支持兩種定義目錄的方式:

  1. catalog(單數):一個用於常用依賴的默認目錄

    json
    "catalog": {
      "react": "^19.0.0",
      "react-dom": "^19.0.0"
    }

    只需使用 catalog: 引用:

    json
    "dependencies": {
      "react": "catalog:"
    }
  2. catalogs(復數):多個命名目錄用於分組依賴

    json
    "catalogs": {
      "testing": {
        "jest": "30.0.0"
      },
      "ui": {
        "tailwind": "4.0.0"
      }
    }

    使用 catalog:<name> 引用:

    json
    "dependencies": {
      "jest": "catalog:testing",
      "tailwind": "catalog:ui"
    }

使用目錄的好處

  • 一致性:確保所有包使用相同版本的關鍵依賴
  • 維護:在一個地方更新依賴版本,而不是在多個 package.json 文件中更新
  • 清晰:清楚地表明哪些依賴在你的 monorepo 中是標准化的
  • 簡單:不需要復雜的版本解析策略或外部工具

實際示例

這是一個更全面的 React 應用程序示例:

根 package.json

json
{
  "name": "react-monorepo",
  "workspaces": {
    "packages": ["packages/*"],
    "catalog": {
      "react": "^19.0.0",
      "react-dom": "^19.0.0",
      "react-router-dom": "^6.15.0"
    },
    "catalogs": {
      "build": {
        "webpack": "5.88.2",
        "babel": "7.22.10"
      },
      "testing": {
        "jest": "29.6.2",
        "react-testing-library": "14.0.0"
      }
    }
  },
  "devDependencies": {
    "typescript": "5.1.6"
  }
}
json
{
  "name": "app",
  "dependencies": {
    "react": "catalog:",
    "react-dom": "catalog:",
    "react-router-dom": "catalog:",
    "@monorepo/ui": "workspace:*",
    "@monorepo/utils": "workspace:*"
  },
  "devDependencies": {
    "webpack": "catalog:build",
    "babel": "catalog:build",
    "jest": "catalog:testing",
    "react-testing-library": "catalog:testing"
  }
}
json
{
  "name": "@monorepo/ui",
  "dependencies": {
    "react": "catalog:",
    "react-dom": "catalog:"
  },
  "devDependencies": {
    "jest": "catalog:testing",
    "react-testing-library": "catalog:testing"
  }
}
json
{
  "name": "@monorepo/utils",
  "dependencies": {
    "react": "catalog:"
  },
  "devDependencies": {
    "jest": "catalog:testing"
  }
}

更新版本

要在所有包中更新版本,只需在根 package.json 中更改版本:

json
"catalog": {
  "react": "^19.1.0",  // 從 ^19.0.0 更新
  "react-dom": "^19.1.0"  // 從 ^19.0.0 更新
}

然後運行 bun install 來更新所有包。

鎖文件集成

Bun 的鎖文件跟蹤目錄版本,使得在不同環境中確保一致的安裝變得容易。鎖文件包括:

  • 來自 package.json 的目錄定義
  • 每個目錄依賴的解析
json
{
  "lockfileVersion": 1,
  "workspaces": {
    "": {
      "name": "react-monorepo",
    },
    "packages/app": {
      "name": "app",
      "dependencies": {
        "react": "catalog:",
        "react-dom": "catalog:",
        ...
      },
    },
    ...
  },
  "catalog": {
    "react": "^19.0.0",
    "react-dom": "^19.0.0",
    ...
  },
  "catalogs": {
    "build": {
      "webpack": "5.88.2",
      ...
    },
    ...
  },
  "packages": {
    ...
  }
}

限制和邊界情況

  • 目錄引用必須匹配 catalog 或命名 catalogs 之一中定義的依賴
  • 目錄名稱中的空字符串和空格將被忽略(視為默認目錄)
  • 目錄中的無效依賴版本將在 bun install 期間無法解析
  • 目錄僅在工作區內可用;它們不能在 monorepo 之外使用

Bun 的目錄系統提供了一種強大而簡單的方法,在你的 monorepo 中保持一致性,而不會給你的工作流引入額外的復雜性。

發布

當你運行 bun publishbun pm pack 時,Bun 會自動將 package.json 中的 catalog: 引用替換為解析後的版本號。發布的包包含常規的 semver 字符串, 不再依賴於你的目錄定義。

Bun學習網由www.bunjs.com.cn整理維護