$ man context-wiki/monorepos
インフラストラクチャintermediate
Monorepo
1 つのリポジトリ、複数のプロジェクト、共有コード、1 回のプッシュですべてデプロイ
なぜ Monorepo なのか
最初は 1 つのウェブサイトを作る予定だった。しかしエージェントと一緒にアーキテクチャを検討した結果、1 つのサイトにはすべてを収められないことが分かった。3 つのオーディエンス、3 つのドメイン。shawnos.ai は個人ブランド用。thegtmos.ai は GTM エンジニア向け。thecontentos.ai はコンテンツクリエイター向け。でも 3 つの別々のリポジトリで、3 セットの依存関係、3 本のデプロイパイプライン、3 つの同じデザインシステムのコピーを持ちたくなかった。だから Monorepo を構築した。1 つのリポジトリに 3 つのサイトを収め、共有コードでつなぐ。1 回のプッシュで 3 つすべてをデプロイ。1 つのデザインシステム。1 つの真実の情報源。
パターン
アーキテクチャの仕組み
Turborepo がオーケストレーションを管理する。どのプロジェクトがどのパッケージに依存しているかを把握し、正しい順序でビルドする。
apps/shawnos/ は shawnos.ai サイト。
apps/gtmos/ は thegtmos.ai サイト。
apps/contentos/ は thecontentos.ai サイト。
packages/shared/ には 3 つのサイトすべてが使うコンポーネント、スタイル、データファイル、ユーティリティが入っている。
共有コンポーネントを更新すれば、3 つのサイトすべてにその更新が反映される。新しいデータファイル(このウィキのような)を追加するときは packages/shared/data/ に置けば、どのサイトからでもインポートできる。共有パッケージは橋渡しだ。サイトはそこからインポートする。コードの複製は決してしない。
プロのコツ
別々のリポジトリと比べたメリット
1 回のコミットで 3 つのサイトを更新できる。共有ナビゲーションコンポーネントのバグを修正すれば、1 回のプッシュで 3 つのサイトすべてに修正が反映される。リポジトリ間の同期は不要。
型とデータの共有。ウィキデータファイル、RPG 成長システム、ボイスコンポーネント。すべて packages/shared/ にある。一度書けば、どこでも使える。
依存関係の一貫性。3 つのサイトすべてが同じバージョンの Next.js、React、その他すべてのパッケージを使う。リポジトリ間のバージョンのズレが起きない。
1 本のデプロイパイプライン。main にプッシュすれば Vercel が 3 つすべてをビルドし、すべてが公開される。/deploy スキルは 3 つではなく 1 つのリポジトリを管理する。
アンチパターン
Monorepo のコスト
Monorepo はタダではない。Turborepo が複数のプロジェクトをビルドするため、ビルド時間が長くなる。初期セットアップは単一サイトのリポジトリより複雑だ。パッケージのインポートを正しく設定する必要がある(package.json の exports、TypeScript のパス解決)。そして共有パッケージを壊すと、3 つのサイトが同時に壊れる。
プロジェクト間で共有コードがあるなら、このトレードオフは価値がある。プロジェクトが本当に独立していて、共有コンポーネントもデータもないなら、別々のリポジトリの方がシンプルだ。僕の 3 つのサイトはデザインシステム、データファイル、コンポーネント、ユーティリティを共有している。Monorepo のおかげで毎週何時間も節約できている。何も共有していなかったら、3 つのリポジトリを使っていただろう。
knowledge guide
関連記事