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

覆蓋與解析

使用 npm 的 overrides 和 Yarn 的 resolutions 控制元相依版本

Bun 支援 package.json 中 npm 的 "overrides" 和 Yarn 的 "resolutions"。兩者都為_元相依_(即你的相依項的相依)指定版本範圍。

package.json
{
  "name": "my-app",
  "dependencies": {
    "foo": "^2.0.0"
  },
  "overrides": { // [!code ++]
    "bar": "~4.4.0" // [!code ++]
  } // [!code ++]
}

預設情況下,Bun 會根據每個包的 package.json 中指定的版本範圍,安裝所有相依項和元相依項的最新版本。假設你的專案有一個相依項 foo,而 foo 又相依於 bar。這使得 bar 成為專案的一個_元相依項_。

package.json
{
  "name": "my-app",
  "dependencies": {
    "foo": "^2.0.0"
  }
}

當你執行 bun install 時,Bun 會安裝每個包的最新版本。

tree
node_modules
├── foo@2.3.4
└── bar@4.5.6

如果 bar@4.5.6 中引入了安全漏洞,你可能會想要將 bar 固定到一個不包含該漏洞的舊版本。這就是 "overrides" 和 "resolutions" 的用途。


"overrides"

將 bar 新增到 package.json 的 "overrides" 欄位中。Bun 在確定要安裝哪個版本的 bar 時,會遵循指定的版本範圍,無論它是相依項還是間接相依項。

package.json
{
  "name": "my-app",
  "dependencies": {
    "foo": "^2.0.0"
  },
  "overrides": { // [!code ++]
    "bar": "~4.4.0" // [!code ++]
  } // [!code ++]
}

Bun 只會從根目錄的 package.json 讀取 overrides,而不會從工作區包中讀取。Overrides 也會應用於 peerDependencies。

"resolutions"

"resolutions" 是 Yarn 對 "overrides" 的替代方案,語法類似。Bun 支援它,以幫助專案從 Yarn 遷移。

package.json
{
  "name": "my-app",
  "dependencies": {
    "foo": "^2.0.0"
  },
  "resolutions": { // [!code ++]
    "bar": "~4.4.0" // [!code ++]
  } // [!code ++]
}

值

值可以是任何相依項說明符,而不僅僅是版本範圍。npm: 會將一個包替換為一個分支版本,而 catalog:(或 catalog:<name>)會使被覆蓋的版本與一個工作區 catalog保持同步:

package.json
{
  "name": "my-app",
  "overrides": {
    "quux": "npm:@myorg/quux@^1.0.0",
    "foo": "catalog:"
  }
}

"$name" 值會複用你在自己的相依項中為 name 宣告的範圍,因此"bar": "$foo"會將 bar 固定到你為 foo 宣告的範圍

巢狀覆蓋

你可以將規則限定到一個父包,因此它僅適用於該包的直接相依項。Bun 接受 npm 物件形式、pnpm 的 > 形式,以及帶版本範圍的父包:

package.json
{
  "name": "my-app",
  "overrides": {
    "micromatch": {
      ".": "^4.0.5",
      "picomatch": "^2.3.2"
    },
    "micromatch>picomatch": "^2.3.2",
    "micromatch@^4>picomatch": "^2.3.2"
  }
}

物件中的"."會覆蓋 micromatch 本身,其效果類似於頂層的"micromatch"規則

"resolutions" 接受 Yarn 的路徑形式。Bun 為了相容性接受 **,但無論哪種形式,該規則都只會影響父包的直接相依項:

package.json
{
  "name": "my-app",
  "resolutions": {
    "micromatch/picomatch": "^2.3.2",
    "**/micromatch/**/picomatch": "^2.3.2"
  }
}

當多個規則匹配時,最具體的規則優先:帶版本的父包 > 父包 > 頂層

版本範圍覆蓋

鍵可以攜帶版本選擇器,因此規則只會應用於聲明範圍與其重疊的相依包。這是 pnpm audit --fix 寫入的形式:

package.json
{
  "name": "my-app",
  "overrides": {
    "semver@<7.5.2": "7.5.2",
    "webpack>terser@4": "4.8.1",
    "terser@4": {
      ".": "4.8.1"
    }
  }
}

Bun 會將選擇器與每個相依方_宣告_的範圍進行比較,而不是與解析後的版本進行比較。"semver@<7.5.2" 會應用於宣告 ^7.3.0 的相依方(它仍可能選擇 7.3.x),但不會應用於宣告 ^7.5.2 的相依方。使用 dist-tag、catalog:、workspace:、git 或 URL 說明符的相依方永遠不會匹配選擇器。

限制

  • Bun 僅支援一層父包。它會忽略 a>b>c、a/b/c 和更深層的物件巢狀,並行出警告。
  • Bun 不支援 pnpm 的 "pkg@"(空選擇器)和 "-"(移除相依項)形式,並會跳過它們,同時發出警告。
  • Bun 會將包含巢狀規則或版本範圍規則的鎖檔案寫為 lockfileVersion 3,較舊版本的 Bun 無法讀取。