pnpm v9 Catalogsを用いたモノレポ全体の依存バージョン一元管理

pnpm Monorepo Node.js DevOps
結論

pnpm-workspace.yamlcatalog: でバージョンを一元管理し、ズレを未然に防ぎます。

# pnpm公式仕様:pnpm-workspace.yaml での Catalogs 定義
packages:
  - 'apps/*'
  - 'packages/*'

# ⭕ モノレポ共通依存のバージョンを一元固定
catalog:
  react: ^18.3.1
  react-dom: ^18.3.1
  typescript: ^5.5.0
// 各サブパッケージ (apps/web/package.json) での参照
{
  "name": "web-app",
  "dependencies": {
    "react": "catalog:",
    "react-dom": "catalog:"
  },
  "devDependencies": {
    "typescript": "catalog:"
  }
}

pnpm v9公式仕様:Catalogs 機能によるメリット

pnpm公式ドキュメント(pnpm.io/workspaces#catalogs)の規定通り、pnpm v9 から導入された Catalogs は、モノレポ全体の依存関係を一元化する標準機能です。

  1. pnpm-workspace.yaml に一度記述するだけ: 各 package.json を個別に修正し回る必要がなく、1箇所書き換えるだけで全サブプロジェクトが一斉更新
  2. catalog: プロトコル仕様: 指定されたパッケージは自動的にルートカタログの正確なバージョンに同期

実際に起こる障害:モノレポ内での依存バージョン分裂(Dependency Drift)事故

Catalogs を使用せず、サブパッケージごとに package.jsonreact: ^18.2.0react: ^18.3.1 を個別に指定している場合、以下の大障害が発生します。

  • 二重バンドル障害 (Multiple React Instances): アプリ内に 2つの異なるバージョンの React が同時にロードされ、Invalid Hook CallReact.useState の参照崩壊でアプリが真っ白にクラッシュする
  • 型不整合障害 (TS2322): パッケージ A の TypeScript 型とパッケージ B の型にミスマッチが生じ、CIビルドが全落する

導入の手順

  1. リポジトリ直下の pnpm-workspace.yamlcatalog: セクションを追加し、主要ライブラリ(React, TypeScript, Next.js等)の指定バージョンを集中定義する
  2. モノレポ内の全 package.json のバージョン表記を "catalog:" に書き換える
  3. pnpm install を実行し、全パッケージが同一バージョンの単一シンボリックリンクを参照しているか検証する