Bun はパッケージマネージャーとしても利用できるので、npm の workspaces によるモノレポ管理も可能です。モノレポとは、複数のパッケージを 1 つのリポジトリで管理することです。モノレポを利用することで、同レポジトリ内のパッケージを互いに参照したり、node_modules をシェアしてディスク容量を節約するといったメリットがあります。
この記事では、Bun workspace を利用してモノレポを管理する方法を紹介します。
Bun workspace の使い方
workspace ではディレクトリのルートレベルに、各パッケージを管理するためのルートパッケージが必要です。ルートパッケージは通常 dependencies または devDependencies のフィールドを含みません。workspaces フィールドには、ワークスペースとして管理するパッケージのパスを配列で指定します。* を指定することで、特定のディレクトリにある全てのディレクトリをワークスペースとして管理できます。以下の例では、packages ディレクトリにある全てのディレクトリをワークスペースとして管理しています。
また、ルートパッケージは誤って npm に publish しないために、private フィールドを true に設定することが推奨されています。
{
"name": "sample-workspace",
"private": true,
"workspaces": [
"packages/*"
]
}ルートパッケージの作成が完了したので、packages ディレクトリ配下にパッケージを作成していきましょう。以下の 3 つのパッケージを作成します。
packages/apppackages/libpackages/ui
ディレクトリの構成は以下のようになります。
.
├── packages
│ ├── app
| | └── package.json
│ ├── lib
| | └── package.json
│ └── ui
| └── package.json
├── package.json
├── bun.lockb
└── node_modulespackages/lib パッケージにのみ特定のライブラリをインストールしてみましょう。その場合、該当のディレクトリに移動してから bun add コマンドを実行します。
cd packages/lib
bun add dayjsbun add コマンドを実行した後、packages/lib/package.json に dayjs が追加されます。さらにルートディレクトリに bun.lockb ファイルが作成されます。
{
"name": "lib",
"version": "0.0.0",
"dependencies": {
"dayjs": "^1.11.9"
}
}packages/lib パッケージで他のパッケージから参照される関数を定義してみましょう。packages/lib パッケージの src/index.ts に以下のコードを追加します。
import dayjs from "dayjs";
export const format = (date: Date) => dayjs(date).format("YYYY-MM-DD");bun build コマンドを実行して、packages/lib パッケージをビルドします。
bun build ./index.ts --outdir=dist/index.jspackages/lib/dist/index.js が作成されます。packages/lib の package.json の main フィールドを dist/index.js に変更します。main フィールドでは、パッケージのエントリーポイントを指定します。
{
"name": "lib",
"version": "0.0.0",
"main": "dist/index.js",
"dependencies": {
"dayjs": "^1.11.9"
}
}packages/app パッケージから packages/lib パッケージを参照してみましょう。同じレポジトリの別のパッケージを参照するためには、パッケージの利用者の package.json の dependencies または devDependencies フィールドに、参照するパッケージ名を直接指定します。同レポジトリ内のパッケージであることを示すため、バージョンフィールドには、"workspace:*" を指定する必要があります。
packages/app/package.json を以下のように変更します。
{
"name": "app",
"version": "0.0.0",
"dependencies": {
"lib": "workspace:*"
}
}その後、ルートディレクトリで bun install コマンドを実行します。
bun installpackages/app から実際に lib パッケージを使ってみましょう。packages/app パッケージの src/index.ts に以下のコードを追加します。
import { format } from "lib";
const date = new Date();
console.log(format(date));以下のコマンドでコードを実行します。
cd packages/app
bun run src/index.tsx現在の時刻がフォーマットされて出力されれば成功です。
2023-09-15まとめ
- Bun workspace では、
workspacesフィールドによって、ワークスペースとして管理するパッケージのパスを指定します。 - 個別のパッケージで
bun addコマンドを実行して依存ライブラリをインストールする - 同じレポジトリ内のパッケージを参照するためには、パッケージ名を直接指定して、バージョンフィールドには、
"workspace:*"を指定する
