如果在工作目錄或更高層目錄中找不到 node_modules 目錄,Bun 將放棄 Node.js 風格的模塊解析,轉而使用 Bun 模塊解析算法。
在 Bun 風格的模塊解析下,所有導入的包在執行期間都會自動安裝到 全局模塊緩存 中(與 bun install 使用的緩存相同)。
ts
import { foo } from "foo"; // 安裝 latest 版本
foo();第一次運行此腳本時,Bun 將自動安裝 "foo" 並緩存它。下次運行腳本時,將使用緩存的版本。
版本解析
要確定安裝哪個版本,Bun 遵循以下算法:
- 檢查項目根目錄中是否存在
bun.lock文件。如果存在,使用鎖文件中指定的版本。 - 否則,向上掃描查找包含
"foo"作為依賴的package.json。如果找到,使用指定的 semver 版本或版本范圍。 - 否則,使用
latest。
緩存行為
一旦確定版本或版本范圍,Bun 將:
- 檢查模塊緩存中是否存在兼容版本。如果存在,使用它。
- 解析
latest時,Bun 將檢查package@latest是否已在過去 24 小時 內下載並緩存。如果是,使用它。 - 否則,從
npm注冊表下載並安裝相應版本。
安裝
包被安裝並緩存到 <cache>/<pkg>@<version>,因此同一包的多個版本可以同時緩存。此外,在 <cache>/<pkg>/<version> 下創建符號鏈接,以便更快地查找緩存中存在的包的所有版本。
版本說明符
通過在導入語句中直接指定版本或版本范圍,可以完全繞過整個解析算法。
ts
import { z } from "zod@3.0.0"; // 特定版本
import { z } from "zod@next"; // npm 標簽
import { z } from "zod@^3.20.0"; // semver 范圍優勢
這種自動安裝方法在以下幾個方面很有用:
- 空間效率 — 每個依賴版本在磁盤上只存在一處。與每個項目重復安裝相比,這節省了大量空間和時間。
- 可移植性 — 要共享簡單的腳本和代碼片段,你的源文件是 自包含的。無需將代碼和配置文件一起
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