覆蓋與解析
使用 npm 的 overrides 和 Yarn 的 resolutions 控制元相依版本
Bun 支援 package.json 中 npm 的 "overrides" 和 Yarn 的 "resolutions"。兩者都為_元相依_(即你的相依項的相依)指定版本範圍。
{
"name": "my-app",
"dependencies": {
"foo": "^2.0.0"
},
"overrides": { // [!code ++]
"bar": "~4.4.0" // [!code ++]
} // [!code ++]
}
預設情況下,Bun 會根據每個包的 package.json 中指定的版本範圍,安裝所有相依項和元相依項的最新版本。假設你的專案有一個相依項 foo,而 foo 又相依於 bar。這使得 bar 成為專案的一個_元相依項_。
{
"name": "my-app",
"dependencies": {
"foo": "^2.0.0"
}
}
當你執行 bun install 時,Bun 會安裝每個包的最新版本。
node_modules
├── foo@2.3.4
└── bar@4.5.6
如果 bar@4.5.6 中引入了安全漏洞,你可能會想要將 bar 固定到一個不包含該漏洞的舊版本。這就是 "overrides" 和 "resolutions" 的用途。
"overrides"
將 bar 新增到 package.json 的 "overrides" 欄位中。Bun 在確定要安裝哪個版本的 bar 時,會遵循指定的版本範圍,無論它是相依項還是間接相依項。
{
"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 遷移。
{
"name": "my-app",
"dependencies": {
"foo": "^2.0.0"
},
"resolutions": { // [!code ++]
"bar": "~4.4.0" // [!code ++]
} // [!code ++]
}
值
值可以是任何相依項說明符,而不僅僅是版本範圍。npm: 會將一個包替換為一個分支版本,而 catalog:(或 catalog:<name>)會使被覆蓋的版本與一個工作區 catalog保持同步:
{
"name": "my-app",
"overrides": {
"quux": "npm:@myorg/quux@^1.0.0",
"foo": "catalog:"
}
}
"$name" 值會複用你在自己的相依項中為 name 宣告的範圍,因此"bar": "$foo"會將 bar 固定到你為 foo 宣告的範圍
巢狀覆蓋
你可以將規則限定到一個父包,因此它僅適用於該包的直接相依項。Bun 接受 npm 物件形式、pnpm 的 > 形式,以及帶版本範圍的父包:
{
"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 為了相容性接受 **,但無論哪種形式,該規則都只會影響父包的直接相依項:
{
"name": "my-app",
"resolutions": {
"micromatch/picomatch": "^2.3.2",
"**/micromatch/**/picomatch": "^2.3.2"
}
}
當多個規則匹配時,最具體的規則優先:帶版本的父包 > 父包 > 頂層
版本範圍覆蓋
鍵可以攜帶版本選擇器,因此規則只會應用於聲明範圍與其重疊的相依包。這是 pnpm audit --fix 寫入的形式:
{
"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 會將包含巢狀規則或版本範圍規則的鎖檔案寫為
lockfileVersion3,較舊版本的 Bun 無法讀取。