Use npm Workspaces for Monorepo Management
コンテキスト
Section titled “コンテキスト”複数の関連プロジェクトを統一管理するためのmonorepo戦略が必要である。従来、単一のリポジトリで複数のパッケージを管理する場合、依存関係の管理、ビルド順序の制御、バージョン管理などが煩雑になる課題があった。
現在のプロジェクト構成では、以下の要件を満たすmonorepo管理ツールが必要である。
- 共通ライブラリとアプリケーションの同時開発
- パッケージ間の依存関係の一元管理(重複インストールの回避)
- 開発環境のセットアップの簡素化
- CI/CDパイプラインでの並列ビルド・テスト実行
- ツールベンダーへの過度な依存を避けること
monorepo管理にnpm workspacesを採用する。Node.jsエコシステムの標準機能を活用することで、サードパーティツールへのロックインを避け、シンプルで安定した開発体験を提供する。
選択肢1: npm workspaces(採用案)
Section titled “選択肢1: npm workspaces(採用案)”-
利点:
- Node.jsエコシステムの標準機能(ベンダーロックインなし)
- 追加のツールインストールが不要
- シンプルな設定(package.jsonのみ)
- npmの標準コマンドで操作可能
- 依存関係の重複解決(hoisting)が自動
- CI/CDでの設定が簡単
- 学習コストが低い
-
欠点:
- 高度な機能(キャッシュ、タスクランナー等)は別途実装が必要
- ビルド最適化機能が限定的
- 大規模monorepoでのパフォーマンス制約
- タスクの並列実行制御が基本的
選択肢2: Turborepo
Section titled “選択肢2: Turborepo”-
利点:
- 高速なビルドキャッシュシステム
- インクリメンタルビルド対応
- タスクの並列実行最適化
- 優れたDX(Developer Experience)
-
欠点:
- Vercel社への依存(ベンダーロックイン)
- 設定の複雑性
- 新しいツールのため長期安定性が未知数
- 追加の学習コストと設定管理
選択肢3: Nx
Section titled “選択肢3: Nx”-
利点:
- 豊富な機能セット(ジェネレーター、キャッシュ等)
- 大規模プロジェクト向けの最適化
- 多言語サポート
- 成熟したエコシステム
-
欠点:
- 複雑な設定と学習コストが高い
- Nx社への依存
- オーバーエンジニアリングになりやすい
- 小規模プロジェクトには過剰
選択肢4: Lerna
Section titled “選択肢4: Lerna”-
利点:
- 長い開発履歴と安定性
- バージョン管理機能が充実
- 豊富なドキュメントとコミュニティ
-
欠点:
- メンテナンスが停滞している
- 現代的なworkspace機能が不足
- パフォーマンスが劣る
- 新機能の追加が期待できない
この決定による影響を記述する。
-
ポジティブな影響:
- ベンダーロックインを回避し、長期的な安定性を確保
- セットアップと運用が簡単で、チーム全体の習得が容易
- npmエコシステムの標準に従うことで、互換性問題が少ない
- CI/CDパイプラインの設定が簡素化される
- 依存関係の管理が透明で予測可能
-
ネガティブな影響:
- 大規模プロジェクトでのビルド最適化が限定的
- 高度な機能は追加実装が必要
- キャッシュ機能が基本的
-
リスク:
- プロジェクト規模拡大時にパフォーマンス問題が発生する可能性
- 複雑なタスク依存関係の管理が困難になる場合がある
- 他のツールと比較して機能的制約がある
実装ガイドライン
Section titled “実装ガイドライン”基本的なpackage.json設定
Section titled “基本的なpackage.json設定”{ "name": "project-root", "private": true, "workspaces": [ "packages/*", "apps/*" ], "scripts": { "build": "npm run build --workspaces", "test": "npm run test --workspaces", "lint": "npm run lint --workspaces", "dev": "npm run dev --workspace=web" }, "devDependencies": { "@company/eslint-config": "*", "typescript": "^5.0.0" }}ディレクトリ構造
Section titled “ディレクトリ構造”project-root/├── package.json├── apps/│ ├── web/│ │ └── package.json│ └── mobile/│ └── package.json├── packages/│ ├── ui-components/│ │ └── package.json│ ├── shared-utils/│ │ └── package.json│ └── types/│ └── package.json└── tools/ └── build-config/ └── package.jsonworkspace間の依存関係
Section titled “workspace間の依存関係”{ "name": "@company/web", "dependencies": { "@company/ui-components": "*", "@company/shared-utils": "*" }}よく使うコマンド
Section titled “よく使うコマンド”# 特定のworkspaceでコマンド実行npm run build --workspace=web
# 全workspaceでコマンド実行npm run test --workspaces
# workspaceにパッケージを追加npm install lodash --workspace=apps/web
# workspace間の依存関係を追加npm install @company/ui-components --workspace=apps/webCI/CD最適化
Section titled “CI/CD最適化”# GitHub Actions例- name: Install dependencies run: npm ci
- name: Build all packages run: npm run build --workspaces
- name: Test changed packages run: npm run test --workspaces --if-present