作業ディレクトリまたはその上位に node_modules ディレクトリが存在しない場合、Bun は Node.js スタイルのモジュール解決を放棄し、Bun モジュール解決アルゴリズム を使用します。
Bun スタイルのモジュール解決では、インポートされたすべてのパッケージは実行中に グローバルモジュールキャッシュ に自動的にインストールされます(bun install で使用されるのと同じキャッシュ)。
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> の下にシンボリックリンクが作成されます。
バージョン指定子
インポート文にバージョンまたはバージョン範囲を直接指定することで、この解決アルゴリズム全体を短絡させることができます。
import { z } from "zod@3.0.0"; // 特定のバージョン
import { z } from "zod@next"; // npm タグ
import { z } from "zod@^3.20.0"; // semver 範囲メリット
この自動インストールアプローチには、いくつかの理由で役立ちます。
- スペース効率 — 依存関係の各バージョンは、ディスク上の 1 か所にのみ存在します。これは、プロジェクトごとの冗長なインストールと比較して、大幅なスペースと時間の節約になります。
- 移植性 — 単純なスクリプトや 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 のサポートはありません
FAQ
これは pnpm の動作とどのように異なりますか?
pnpm では、pnpm install を実行する必要があり、ランタイムが解決するための node_modules フォルダがシンボリックリンクとして作成されます。対照的に、Bun はファイルを実行する際に依存関係をその場で解決します。事前に install コマンドを実行する必要はありません。また、Bun は node_modules フォルダも作成しません。
これは Yarn Plug'N'Play の動作とどのように異なりますか?
Yarn では、スクリプトを実行する前に yarn install を実行する必要があります。対照的に、Bun はファイルを実行する際に依存関係をその場で解決します。事前に install コマンドを実行する必要はありません。
Yarn Plug'N'Play は依存関係を格納するために zip ファイルを使用します。これにより、依存関係の読み込みは ランタイムで遅く なります。zip ファイルへのランダムアクセス読み取りは、同等のディスク検索よりも遅くなる傾向があるためです。
これは Deno の動作とどのように異なりますか?
Deno では、npm の import ごとに npm: 指定子が必要で、tsconfig.json の compilerOptions.paths によるインポートマップのサポートがなく、package.json の設定のサポートが不完全です。Deno とは異なり、Bun は現在 URL インポートをサポートしていません。