npm workspace で TypeScript 環境の素朴なモノレポを作るには
というテーマで素朴なやつを作った
https://github.com/yoshikouki/monorepo-sandbox
条件は以下。おそらく条件は満たせている・・・と思う
apps 配下の各プロジェクトは、packages/db を利用する
apps 配下の各プロジェクトは、packages/db を TypeScript のままインポートしたい
apps 配下の各プロジェクトのビルド時は、packages/db も一緒にビルドされる
プロジェクト構成
❯ tree --gitignore .
.
├── Dockerfile
├── apps
│ └── api
│ ├── package.json
│ ├── src
│ │ └── index.ts
│ └── tsconfig.json
├── docker-compose.yaml
├── package-lock.json
├── package.json
├── packages
│ └── db
│ ├── package.json
│ ├── prisma
│ │ ├── migrations
│ │ │ ├── 20240613112605_init
│ │ │ │ └── migration.sql
│ │ │ └── migration_lock.toml
│ │ └── schema.prisma
│ ├── src
│ │ └── index.ts
│ └── tsconfig.json
└── tsconfig.json
packages/db に Prisma のようなDBClientを配置しておいて
import { PrismaClient } from '@prisma/client'
export const db = new PrismaClient()
apps/api から import する。Next.js などで作った apps/web のような別プロジェクトからも利用できることを想定している。今回はスコープ機能 "@scope/db" は使わなかった
import { db } from 'db';
import express from "express";
const app = express();
const port = 3333;
app.get("/", async (req, res) => {
const id = crypto.randomUUID()
await db.user.create({
data: {
email: `${id}@example.com`,
name: `User ${id}`,
},
})
const allUsers = await db.user.findMany()
console.log(allUsers.length)
res.send(`Users count: ${allUsers.length}`);
});
app.listen(port, () => {
console.log(`Example app listening on port ${port}`);
});
![](https://assets.st-note.com/img/1718285931522-ygrIN6h341.png?width=1200)
設定
root
./package.json
{
"name": "monorepo-sandbox",
"version": "1.0.0",
"private": true,
"scripts": {
"build": "npm run build -w api"
},
"workspaces": [
"packages/db",
"apps/api"
],
"devDependencies": {
"@types/node": "^20.14.2",
"ts-node": "^10.9.2",
"typescript": "^5.4.5"
}
}
packages/db
packages/db/package.json
{
"name": "db",
"version": "1.0.0",
"main": "dist/index.js",
"types": "dist/index.d.ts",
"scripts": {
"build": "tsc --build"
},
"devDependencies": {
"prisma": "^5.15.0"
},
"dependencies": {
"@prisma/client": "^5.15.0"
}
}
main と types が重要。ビルド後に参照するファイルを指している
packages/db/tsconfig.json
{
"compilerOptions": {
"outDir": "dist",
"rootDir": "src",
"composite": true,
"declaration": true,
"declarationMap": true,
"esModuleInterop": true,
"skipLibCheck": true
},
"include": ["src"],
"exclude": ["node_modules", "dist"]
}
apps/api
apps/api/package.json
{
"name": "api",
"version": "1.0.0",
"main": "index.js",
"scripts": {
"build": "tsc --build"
},
"dependencies": {
"express": "^4.19.2"
},
"devDependencies": {
"@types/express": "^4.17.21"
}
}
依存関係に "db" が存在しないことに注目
apps/api/tsconfig.json
{
"compilerOptions": {
"outDir": "dist",
"rootDir": "src",
"composite": true,
"declaration": true,
"declarationMap": true,
"esModuleInterop": true,
"skipLibCheck": true
},
"include": ["src"],
"exclude": ["node_modules", "dist"],
"references": [
{ "path": "../../packages/db" }
]
}
おわりに
おそらく最小構成になっているはずだ
この記事が気に入ったらサポートをしてみませんか?