執行環境套件管理器打包器測試執行器程式碼檢查格式化指南參考部落格意見回饋

工作區

開發包含多個獨立包的複雜多包儲存庫(monorepo)

Bun 支援在 package.json 中設定 workspaces。藉助工作區,你可以在單個儲存庫中開發多個獨立的包,這種儲存庫稱為 monorepo。

多包儲存庫通常具有以下結構:

File
<root>
├── README.md
├── bun.lock
├── package.json
├── tsconfig.json
└── packages
    ├── pkg-a
    │   ├── index.ts
    │   ├── package.json
    │   └── tsconfig.json
    ├── pkg-b
    │   ├── index.ts
    │   ├── package.json
    │   └── tsconfig.json
    └── pkg-c
        ├── index.ts
        ├── package.json
        └── tsconfig.json

根目錄 package.json 中的 "workspaces" 鍵列出了要作為工作區處理的子目錄。按照慣例,這些目錄位於名為 packages 的目錄中。

package.json
{
  "name": "my-project",
  "version": "1.0.0",
  "workspaces": ["packages/*"],
  "devDependencies": {
    "example-package-in-monorepo": "workspace:*"
  }
}
package.json
{
  "name": "my-project",
  "version": "1.0.0",
  "workspaces": ["packages/**", "!packages/**/test/**", "!packages/**/template/**"]
}

每個工作區都有自己的 package.json。要引用多包儲存庫中的另一個包,請在 package.json 中將 semver 範圍或工作區協議(例如 workspace:*)用作版本。

packages/pkg-a/package.json
{
  "name": "pkg-a",
  "version": "1.0.0",
  "dependencies": {
    "pkg-b": "workspace:*"
  }
}

bun install 會為多包儲存庫中的所有工作區安裝相依,並在可能的情況下對包進行去重。若只想為特定工作區安裝相依,請使用 --filter 標誌。

bash
# 安裝所有以 `pkg-` 開頭且不包含 `pkg-c` 的工作區相依
bun install --filter "pkg-*" --filter "!pkg-c"

# 也可以使用路徑,這與上面命令效果相同。
bun install --filter "./packages/pkg-*" --filter "!pkg-c" # 或 --filter "!./packages/pkg-c"

釋出時,Bun 會將 workspace: 版本替換為包的 package.json 版本:

Code
"workspace:*" -> "1.0.1"
"workspace:^" -> "^1.0.1"
"workspace:~" -> "~1.0.1"

指定的版本優先於包 package.json 中的版本:

Code
"workspace:1.0.2" -> "1.0.2" // 即使當前版本是 1.0.1

工作區有幾個主要優點。

  • 將程式碼拆分為邏輯部分。 如果一個包相依於另一個包,請在 package.json 中將其新增為相依項。如果包 b 相依於 a,bun install 會將本地 packages/a 目錄安裝到 node_modules,而不是從 npm 登錄檔下載它。
  • Bun 可以對相依進行去重。 如果 a 和 b 共享一個相依,Bun 會將它_提升_到根目錄的 node_modules 目錄。這可以節省磁碟空間,並儘可能避免同時安裝同一個包的多個版本所導致的“相依地獄”。
  • 在多個包中執行指令碼。 使用 --filter 標誌 一次在多個包中執行 package.json 指令碼,或使用 --workspaces 在所有工作區中執行指令碼。

自包含工作區

使用提升式連結器時,多個工作區共享的相依會被提升到根目錄的 node_modules。有些工具無法處理這種情況:Electron 打包器和無伺服器打包器會遍歷、精簡併重新打包_單個工作區_的 node_modules,並期望每個相依都實際存在於該目錄下。可以在此類工作區的 package.json 中將其標記為自包含(使用 Yarn 所用的相同鍵;只有 "workspaces" 的值會改變佈局):

apps/desktop/package.json
{
  "name": "desktop",
  "installConfig": { "hoistingLimits": "workspaces" }
}

也可以在根目錄的 package.json 中,緊挨著工作區 glob 的位置進行設定:

package.json
{
  "workspaces": {
    "packages": ["apps/*", "packages/*"],
    "selfContained": ["apps/desktop"]
  }
}

(條目可以是工作區路徑或包名稱)

對於該工作區,bun install 會將其視為提升屏障——它直接或間接相依的所有內容(包括通過它所相依的其他工作區引入的內容)都不會被放置在 apps/desktop/node_modules 之上,因此該目錄包含完整的相依樹;這些包會以實際副本的形式安裝,而不是從快取建立硬連結/克隆,因此重寫這些包的工具不會影響快取或其他專案。其他所有工作區仍會像往常一樣將相依提升到根目錄。鎖檔案不會記錄此設定。Bun 每次安裝時都會從 package.json 中讀取該設定,包括使用 --frozen-lockfile 時,因此無論是否啟用此設定,鎖檔案都相同。此設定對隔離式連結器無效,因為在該模式下,每個包本來就只會解析自身的相依。

使用 Catalogs 共享版本

當許多軟體包需要使用相同的相依版本時,請在根目錄的 package.json 中的 catalog 裡統一定義這些版本,然後在工作區中通過 catalog: 協議引用它們。更新 catalog 會同步更新所有引用它的軟體包。請參閱 Catalogs。