アプリ5個を1つのリポジトリで - 個人開発者のTurborepoモノレポ
複数のアプリとWebを1つのリポジトリで管理するTurborepoモノレポの構成法。共通設定の共有、キャッシュでビルドを節約、アプリごとのデプロイまで実践目線でまとめました。
要点まとめ
ひとりでアプリを複数作ると設定が散らばる。Turborepoモノレポでeslint・tsconfigをpackagesとして共有し、turboキャッシュで変わっていないアプリは再ビルドせず、--filterでアプリごとにデプロイする。
目次
ひとりでアプリを作っていると、リポジトリがどんどん増えていきます。アプリ1つ、Web 1つ、またアプリ1つ… そしてeslint設定を5回コピペすることになります。私はこれを1つのモノレポにまとめました。
散らばった設定こそ本当の問題
リポジトリが多いとき一番痛いのは、コードではなく設定です。
- eslint・prettier・tsconfigをリポジトリごとにコピー
- ルールを1つ変えたら全部を巡回して修正
- 共通UI・ユーティリティをnpmに上げるには些細すぎる
モノレポは、これを1か所で共有する方式に変えてくれます。
基本構成
apps/
├── web/ # 랜딩
├── blog/ # 이 블로그
├── wave/ # 오늘의 파도
└── ...
packages/
├── eslint-config/ # 공용 eslint
└── typescript-config/ # 공용 tsconfig
apps/* は実際のデプロイ対象、packages/* はアプリたちが共有する設定・コードです。各アプリの tsconfig.json はこう継承するだけです。
{ "extends": "@repo/typescript-config/nextjs.json" }
これでルールは packages の1か所だけで直せます。
turboキャッシュが核心
Turborepoの本当の武器はキャッシュです。各タスクの入力(ソース・設定)が変わっていなければ、以前の結果をそのまま再利用します。
turbo run build # 전체 빌드(바뀐 것만 실제로 돎)
turbo run build --filter=blog # blog 앱만
turbo.json にタスク間の依存と出力だけ宣言すればOKです。
{
"tasks": {
"build": { "dependsOn": ["^build"], "outputs": [".next/**"] }
}
}
2回目のビルドからは「FULL TURBO」で数秒で終わります。
アプリごとにデプロイする
1つのリポジトリでも、デプロイはアプリごとに分離されます。Dockerなら turbo prune で該当アプリのサブツリーだけ切り出して、イメージを軽くできます。
turbo prune blog --docker # blog + 내부 의존성만 남긴 out/ 생성
このブログもこうやって切り出して、ミニPCにDockerで載せました。その話はセルフホスティングの記事で扱っています。
まとめ
apps/*= デプロイ対象、packages/*= 共有設定- tsconfig・eslintは継承で1か所管理
turboキャッシュで変わっていないアプリは再ビルドしない--filter・pruneでアプリごとにデプロイ
ひとりで複数のプロダクトを運用するなら、モノレポは贅沢ではなく生存ツールです。
よくある質問
アプリが何個からモノレポが得になりますか?
2個を超えた時点で、共通設定(eslint・tsconfig・UI)が生まれるなら得です。設定を1か所で直してすべてのアプリに反映されるのが核心です。
ビルドが遅くなりませんか?
むしろ速くなります。turboは入力が変わっていないタスクの結果をキャッシュして、変わったアプリだけ再ビルドします。
関連記事
- 💻 開発
1つのバケットに所有者が2人いると、最後にapplyした側が勝つ
S3のlifecycleルールを1つ追加したらterraform applyが失敗した。原因は、同じバケットのlifecycle設定を2つのリソースがそれぞれ所有する構造。S3のlifecycleはルール単位ではなくドキュメント単位なので、最後の勝者が相手のルールを静かに消す。
- 💻 開発
テストは緑なのに、通知は一度も送信されていなかった
キューにジョブを入れるコードが初日から毎回失敗していた。エラーは握りつぶされ、テストはモックのおかげで緑のまま。コロン一文字が3つの機能を静かに殺した話。
- 💻 開発
DBが落ちたという通知が来た。DBは一度も落ちていなかった
1日のうちにCRITICALの通知が4つたまった。504、Prisma P2028、管理画面の500、そして「DATABASEサービスダウン」。RDSの指標をまず開いたら、21時間ずっとCPU最大19.7%で無事だった。遅かったのはDBではなく、大西洋を25回渡る往復であり、「ダウン」の通知はヘルスチェックが自分で作り出したものだった。