如果在工作目錄或更上層目錄中找不到 node_modules
目錄,Bun 將放棄 Node.js 風格的模組解析,轉而採用 **Bun 模組解析演算法**。
在 Bun 風格的模組解析下,所有匯入的套件都會在執行期間即時自動安裝到全域模組快取中(與 bun install
使用的快取相同)。
import { foo } from "foo"; // install `latest` version
foo();
第一次執行此腳本時,Bun 會自動安裝 "foo"
並快取它。下次執行腳本時,它將使用快取版本。
版本解析
為了確定要安裝哪個版本,Bun 遵循以下演算法
- 檢查專案根目錄中是否有
bun.lock
檔案。如果存在,則使用鎖定檔中指定的版本。 - 否則,向上掃描目錄樹,尋找包含
“foo”
作為依賴項的package.json
。如果找到,則使用指定的 semver 版本或版本範圍。 - 否則,使用
latest
。
快取行為
一旦確定了版本或版本範圍,Bun 將會
- 檢查模組快取中是否有相容版本。如果有的話,就使用它。
- 當解析
latest
時,Bun 會檢查package@latest
是否在過去 24 小時 內已被下載並快取。如果是,則使用它。 - 否則,從
npm
註冊表下載並安裝適當的版本。
安裝
套件會被安裝並快取到 <cache>/<pkg>@<version>
,因此可以同時快取同一個套件的多個版本。此外,會在 <cache>/<pkg>/<version>
下建立一個符號連結,以便更快地查找快取中存在的所有套件版本。
版本指定符
透過在您的 import 語句中直接指定版本或版本範圍,可以繞過整個解析演算法。
import { z } from "zod@3.0.0"; // specific version
import { z } from "zod@next"; // npm tag
import { z } from "zod@^3.20.0"; // semver range
優點
這種自動安裝方法在幾個方面很有用
- 空間效率 — 每個版本的依賴套件在磁碟上只存在於一個位置。與每個專案的冗餘安裝相比,這可以節省大量的空間和時間。
- 可攜性 — 為了分享簡單的腳本和 gist,您的原始碼檔案是自包含的。無需將包含程式碼和設定檔的目錄
zip
在一起。透過import
語句中的版本指定符,甚至不需要package.json
。 - 便利性 — 無需在執行檔案或腳本之前執行
npm install
或bun install
。只需bun run
即可。 - 向後相容性 — 因為 Bun 仍然尊重
package.json
中指定的版本(如果存在),您可以使用單一命令切換到 Bun 風格的解析:rm -rf node_modules
。
限制
- 沒有 Intellisense。IDE 中的 TypeScript 自動完成功能依賴於
node_modules
內類型宣告檔案的存在。我們正在研究各種解決方案來解決這個問題。 - 不支援 patch-package
常見問題
這與 pnpm 的做法有何不同?
這與 Yarn Plug'N'Play 的做法有何不同?
這與 Deno 的做法有何不同?