RQ-053: マルチ-package リポジトリの monorepo 化トポロジー設計のベストプラクティス
RQ ID: RQ-053 作成日: 2026-05-22 調査トリガー: bizlp-gas-accounting リポは現状「準 monorepo」状態 (4 projects・3 deploy targets・npm/pnpm 混在)。root の
pnpm-workspace.yamlがプレースホルダのまま放置され、subproject 追加 (docs-search-worker/drp/) に伴い「monorepo 化したい意思」が発生。ただし「root を monorepo に含めるか否か」を含めた基本方針が未整理。ADR 起案前に業界ベストプラクティスを 3 LLM で並列調査する。 関連 ADR: 未起案 (本リサーチ完了後に ADR-NNNN を起案予定) 3 モデル並列調査: Gemini Deep Research / Claude Research / GPT-4o Deep Research に同一プロンプトを投入する
プロジェクト背景(モデルへの文脈提供)
調査対象プロジェクト (bizlp-gas-accounting) の特性:
- 規模: ソロ開発 (まもなく Jr. 1 名参加予定)。AI エージェント (Claude Code) 主体の開発スタイル
- 構成 (現状の 4 projects):
Project Path Role Deploy 先 依存管理 root (GAS) /(root package.json)法人会計 SaaS の中核 (Google Apps Script V8) + scripts orchestrator Google Apps Script (clasp 経由) npm ( package-lock.json) + pnpm (pnpm-lock.yaml) 混在webapp-client webapp_client/React SPA (4 ターゲットビルド: sidebar / cockpit / multiyear / ocr_bench) GAS HtmlService (templates/ に build 成果物を埋め込み) npm drp drp/LangGraph (TypeScript) 意思決定 pipeline (ADR 起案 workflow) Cloudflare Workers pnpm docs-search-worker docs-search-worker/Claude Sonnet 4.6 による docs 検索 re-ranking Cloudflare Workers pnpm - 現状の結合 (準 monorepo の証跡):
- 型共有:
docs/spec/sidebar_api.d.ts(root) を webapp_client が import (GAS ↔ SPA 契約) - コード同期:
webapp_client/scripts/sync-engines.mjsが prebuild hook で400_domain/*.jsをwebapp_client/src/engines/にコピー (SSoT は GAS 側) - Build orchestrator: root の
npm run build:spaが webapp_client 4 ターゲット ビルドを並行実行
- 型共有:
- 依存管理の課題:
- root:
package-lock.jsonとpnpm-lock.yamlが共存。pnpm-workspace.yamlはallowBuilds: fsevents: set this to true or falseというプレースホルダのままでpackages:フィールド未定義 (= workspace 機能未設定) - subproject: 各自独立 lock。共有 deps (
@anthropic-ai/sdk等) のバージョン不整合リスク
- root:
- AI エージェント前提:
- Claude Code が
find/grep/Readで全 project 横断する。monorepo 化が agent の探索効率に与える影響を考慮すべき - 既存 ADR (ADR-0019 等) で
drp移行を実施済 — 「subproject 化」自体は受容済の architectural pattern
- Claude Code が
- 規模感:
- 個人開発のためビルド時間・CI コスト・ディスクサイズの問題は小さいが、AI agent の探索範囲・型共有・依存統一の方が重要
- クロスプロジェクト変更 (例:
sidebar_api.d.ts更新 → webapp_client + GAS 両側) は頻発する
調査してほしいこと
Q1. Monorepo vs Polyrepo の判断軸
ソロ開発 + AI エージェント前提・複数 deploy target (GAS / Cloudflare Workers / Cloudflare Pages) を抱える状況で、monorepo 化 vs 現状 polyrepo (準-monorepo) 維持の判断基準を教えてください。
- 業界の代表的な判断フレームワーク (Google モノレポ論文 / Microsoft Rush 採用事例 / Babel・Jest・React の monorepo 化動機 / Yarn Workspaces 公式 / pnpm 公式 ガイド)
- 「monorepo に向く / 向かない」の境界条件 (チームサイズ・project 数・deploy target の多様性・言語混在度)
- 個人開発 + AI エージェント主体 という稀な構成での特有の判断軸 (Anthropic / GitHub / Cursor 等の AI コーディング前提リポでの monorepo 採用事例)
- 既に「準-monorepo」状態のリポを「正式 monorepo に昇格させる」/「polyrepo に分離する」の意思決定基準
Q2. Tooling 選択 (workspace manager / build orchestrator)
複数言語・複数 deploy target の monorepo に対する tooling 評価:
- 依存管理層: pnpm workspaces / npm workspaces / Yarn (classic vs Berry) workspaces / Bun workspaces — 機能比較、disk usage、install 速度、CI cache 親和性
- build orchestrator 層: Turborepo / Nx / Bazel / Rush / Lerna (legacy) / Moon — affected detection・remote caching・task pipeline 設計の比較
- 本リポ特有制約への適合性:
- GAS subproject (clasp deploy / TypeScript 非対応 /
.clasp.json切替) との共存 - Cloudflare Workers subproject (wrangler / esbuild) との共存
- React SPA subproject (Vite / 多重ビルド
VITE_BUILD_TARGET) との共存
- GAS subproject (clasp deploy / TypeScript 非対応 /
- 個人開発スケールでの tooling overhead vs 機能のトレードオフ (Bazel は overkill / Lerna は legacy / Turbo vs Nx の文化差)
Q3. Dependency 統一戦略
npm/pnpm 並存 + 各 subproject 独立 lock の現状をどう解消するか:
- 業界の依存統一パターン (root pin / version syncing /
peerDependenciesMeta/resolutions/overrides) - shared deps の hoisting と各 subproject の隔離のバランス (pnpm の
node_modules構造 / strict-peer-deps / shamefully-hoist) - monorepo 化に伴う lock 統合の手順 (各 subproject の lock 削除 → root で一括 install /
pnpm import等の移行ツール) - 「root を monorepo に含めない」選択肢の場合の依存管理 (subproject のみ workspace 化、root は独立 npm project として継続) の現実性
- GAS subproject 固有: deploy 時に
node_modulesを bundle しない (clasp pushは.gsのみ転送) → root の deps を GAS 実行時に持ち込まないコツ
Q4. Build/CI 統合と既存カスタム結合との関係
monorepo 化で CI / build はどう変わるか:
- Turbo/Nx の affected detection (変更 file ベースで影響 subproject を絞り込む) の精度と限界
- 本リポの現状カスタム結合との関係:
webapp_client/scripts/sync-engines.mjsの prebuild hook (400_domain/→webapp_client/src/engines/コピー) を monorepo の依存 graph で表現する方法 (workspace:*link or postinstall script)- root の
npm run build:spaorchestrator を Turbo/Nx の task pipeline で置き換える価値 docs/spec/sidebar_api.d.tsを共有 package 化する vs root 配置のまま import を継続する選択
- Cloudflare Pages / GitHub Actions / clasp deploy との CI 統合 (remote caching の有無 / actions/cache の活用 / PR ごとの affected build)
- AI エージェント (Claude Code) が monorepo CI の build graph を理解しやすい設計 (turbo.json / nx.json の明示性 vs 暗黙的な workspace 推論)
Q5. 段階的移行戦略と推奨アーキテクチャ
本プロジェクト (準 monorepo → 正式 monorepo) の段階的移行を、以下の点を含めて具体的に提案してください:
- root の扱い: root を monorepo に含めるか否かの判断 (GAS の特殊性・既存 scripts 群との関係を踏まえる)。両パターンの IF 構造で提示
- tooling 選択: Q2 の評価を踏まえた本リポへの推奨 (pnpm workspaces + Turbo / pnpm のみ / Nx 等)
- 移行ステップ: Phase 1 (workspace 宣言のみ) → Phase 2 (lock 統合) → Phase 3 (shared package 化) のような段階分け。各 phase の rollback 可能性
- broken pnpm-workspace.yaml の扱い: 現状 root にある未編集テンプレ (
allowBuilds: fsevents: set this to true or false) を削除 / 修正 / 拡張のどれが妥当か - 後戻り可能性: monorepo 化後に polyrepo に戻す必要が生じた場合のコスト試算 (subproject ごとの独立 git history 維持の意義)
- 6 ヶ月後の評価指標: 「monorepo 化が成功だったか」を判定する KPI (build 時間・依存衝突件数・クロスプロジェクト PR 数・AI agent 探索効率)
移行コストは Claude Code 活用前提で試算 (純手動作業での試算は不要)。
出力形式
以下の形式で回答してください:
- TL;DR (3 行以内): 最も重要な推奨を要約
- Q1〜Q5 への回答: 各設問に番号を付けて回答
- 本プロジェクトへの具体的推奨: Q5 の内容を bizlp-gas-accounting プロジェクトに特化した形で具体化 (root 包含可否を明示)
- 他モデルとの比較観点: このモデル固有の知見 (他モデルが見落としがちな観点) があれば明示
結果ファイル保存先
各モデルの回答は以下の filename で保存してください:
- Claude:
RQ-053_monorepo_topology_result_claude.md - Gemini:
RQ-053_monorepo_topology_result_gemini.md - GPT-4o:
RQ-053_monorepo_topology_result_gpt.md
3 モデル全結果が揃ったら、RQ-053_monorepo_topology_synthesis.md を作成して採択方針を決定し、ADR-NNNN (monorepo 化方針) の起草に進む。
以上がプロンプトです。調査対象プロジェクトの文脈に沿って、実践的・具体的な回答をお願いします。