Bun 中的目錄(Catalogs)提供了一種簡單的方法,在 monorepo 中的多個包之間共享通用依賴版本。與其在每個工作區包中重復指定相同的版本,不如在根 package.json 中一次性定義它們,並在整個項目中一致地引用它們。
概述
與傳統的依賴管理不同(每個工作區包需要獨立指定版本),目錄讓你可以:
- 在根 package.json 中定義版本目錄
- 使用簡單的
catalog:協議引用這些版本 - 只需在一個地方更改版本,即可同時更新所有包
這在大型 monorepo 中特別有用,其中數十個包需要使用相同版本的關鍵依賴。
如何使用目錄
目錄結構示例
考慮一個具有以下結構的 monorepo:
my-monorepo/
├── package.json
├── bun.lock
└── packages/
├── app/
│ └── package.json
├── ui/
│ └── package.json
└── utils/
└── package.json1. 在根 package.json 中定義目錄
在根級別的 package.json 中,在 workspaces 對象內添加 catalog 或 catalogs 字段:
{
"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"
}
}
}
}如果你將 catalog 或 catalogs 放在 package.json 文件的頂層,也可以正常工作。
2. 在工作區包中引用目錄版本
在工作區包中,使用 catalog: 協議引用版本:
{
"name": "app",
"dependencies": {
"react": "catalog:",
"react-dom": "catalog:",
"jest": "catalog:testing"
}
}{
"name": "ui",
"dependencies": {
"react": "catalog:",
"react-dom": "catalog:"
},
"devDependencies": {
"jest": "catalog:testing",
"testing-library": "catalog:testing"
}
}3. 運行 Bun Install
運行 bun install 以根據目錄版本安裝所有依賴。
Catalog 與 Catalogs
Bun 支持兩種定義目錄的方式:
catalog(單數):一個用於常用依賴的默認目錄json"catalog": { "react": "^19.0.0", "react-dom": "^19.0.0" }只需使用
catalog:引用:json"dependencies": { "react": "catalog:" }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
{
"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"
}
}{
"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"
}
}{
"name": "@monorepo/ui",
"dependencies": {
"react": "catalog:",
"react-dom": "catalog:"
},
"devDependencies": {
"jest": "catalog:testing",
"react-testing-library": "catalog:testing"
}
}{
"name": "@monorepo/utils",
"dependencies": {
"react": "catalog:"
},
"devDependencies": {
"jest": "catalog:testing"
}
}更新版本
要在所有包中更新版本,只需在根 package.json 中更改版本:
"catalog": {
"react": "^19.1.0", // 從 ^19.0.0 更新
"react-dom": "^19.1.0" // 從 ^19.0.0 更新
}然後運行 bun install 來更新所有包。
鎖文件集成
Bun 的鎖文件跟蹤目錄版本,使得在不同環境中確保一致的安裝變得容易。鎖文件包括:
- 來自 package.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 publish 或 bun pm pack 時,Bun 會自動將 package.json 中的 catalog: 引用替換為解析後的版本號。發布的包包含常規的 semver 字符串, 不再依賴於你的目錄定義。