前提
プロジェクト構成
- core
- 共通処理
- frontend
- core に依存
- api
- core に依存
core のビルド成果物 (*.js) を frontend、api が import する。
core の型 (*.ts) を frontend、api が参照する。
パッケージ管理は Bun を使うが、npm などでもコマンドの差くらいで似たことができると思う。
TypeScript の Project References も簡素に使えそうだが、ts-jest や Playwright は執筆時点でサポートしていない。
今回は Bun などの Workspace を使い、普及した依存関係により、共通処理を参照できるようにする。
共通処理
共通に使う core のパッケージ名を確認する。
パッケージ名は import するときなどよく使う名前になるので大事に考える。
"name": "@my-project/core",
core の外へ出すものを指定する。ここでは core/src/schema/ 以下を出す。
+ "exports": {
+ "./schema/*": {
+ "types": "./src/schema/*.ts",
+ "default": "./dist/schema/*.js"
+ }
+ }
環境別に出し分けることもできるようだが、ここでは共通の *.js を出す。
https://nodejs.org/api/packages.html#conditional-exports
型の参照のために *.ts も出す。
ビルド成果物を参照できるようビルドもしておく。
my-project/core/ $ bun x tsc
Workspace 定義
ルートディレクトリに Workspace を定義する。package.json がなければ作る。
"name": "@my-project/root",
+ "workspaces": [
+ "core/"
+ ],
参照側
frontend が依存する core のパッケージ名を指定する。
"dependencies": {
+ "@my-project/core": "workspace:*",
* の代わりにバージョンの指定もできるようだが、モノレポの規模だと使わないかもしれない。
api も同じく依存する core のパッケージ名を指定する。
"dependencies": {
+ "@my-project/core": "workspace:*",
ルートディレクトリで依存関係をインストールする。
my-project/ $ bun install
インストールされたものを見るとシンボリックリンクになっている。
core をビルドしたら即時に api や frontend へ反映される。
my-project/ $ ls -l node_modules/@my-project/
total 0
(略)core -> ../../core
使ってみる
frontend や api の実装で、core のパッケージ名と exports に指定したビルド成果物を import できるようになる。
import { userTable } from '@my-project/core/schema/users'
少ない変更で簡素に共通処理をまとめる導入ができた。