はじめに
モノレポを運用していると、ある日Claude Codeがnpm installを実行してしまってpackage-lock.jsonが生成されたり、内部パッケージへの依存を"@myorg/ui": "^1.0.0"という実バージョンで書いてしまったりした経験はないだろうか。
Claude Codeはpackage.jsonとpnpm-workspace.yamlを読んでパッケージ構成を把握できる。しかし「内部参照は必ずworkspace:プロトコルを使う」「ルートへの直接インストールは禁止」といったpnpm Workspaces固有のルールは、明示しない限り守ってくれない。
本記事は、pnpm Workspacesの核心機能——workspace:プロトコル、--filter、Catalog——と、Claude CodeがそれをCLAUDE.mdから理解して操作できるように整える方法を解説する。
pnpm Workspacesの基本:pnpm-workspace.yaml と workspace: プロトコル
pnpm-workspace.yaml でパッケージを定義する
モノレポの構成はpnpm-workspace.yamlに書く。ルートディレクトリに1ファイル置くだけで、pnpmが全パッケージの位置を把握する。
# pnpm-workspace.yaml(ルートに配置)
packages:
- "packages/*"
- "apps/*"
- "tools/*"
- "!**/node_modules/**"!プレフィックスで除外パターンを指定できる。globパターンをサポートしており、ネストしたディレクトリも柔軟に扱える。
workspace: プロトコルで内部パッケージを参照する
pnpm独自のworkspace:プロトコルは、モノレポ内のパッケージを内部参照するための仕組みだ。
// packages/app/package.json
{
"dependencies": {
"@myorg/ui": "workspace:*",
"@myorg/utils": "workspace:^1.0.0"
}
}| プロトコル | 意味 |
|---|---|
workspace:* | 常にローカルの最新バージョンを使用 |
workspace:^1.0.0 | ローカル内でsemverの範囲指定 |
workspace:~2.0.0 | パッチバージョンのみ許容 |
workspace:*を使うと、pnpmは外部レジストリへの解決を拒否し、必ずローカルワークスペース内のパッケージを参照する。pnpm publish実行時には自動的に実際のバージョン番号に置換される。つまり開発中はローカルの最新を使いつつ、公開時には正しいバージョンが記録される。
Claude Codeが内部パッケージの依存を追加するとき、"@myorg/ui": "^1.0.0"という書き方をしてしまうと、ローカルを参照せず外部レジストリへ解決しようとする。CLAUDE.mdに「内部参照は必ずworkspace:*を使う」と書いておくだけで、この問題はほぼ起きなくなる。
--filter で「必要なものだけ」を動かす
--filter(省略形: -F)は特定パッケージを絞り込んで操作するためのフラグで、pnpm Workspacesの日常的な作業の中心になる。
# 特定パッケージでスクリプト実行
pnpm --filter @myorg/app run build
# globパターンで複数パッケージ
pnpm --filter "@myorg/*" run lint
# 特定パッケージとその依存先を全てビルド(省略記号 ...)
pnpm --filter @myorg/app... run build
# 特定パッケージに依存しているパッケージを全てテスト(前置 ...)
pnpm --filter ...@myorg/utils run test
# 複数フィルター
pnpm --filter @myorg/app --filter @myorg/api run dev--filter @myorg/app...(後ろに...)は「appとappが依存しているパッケージ全て」を意味し、--filter ...@myorg/utils(前に...)は「utilsに依存しているパッケージ全て」を意味する。前後の...は向きが異なるので注意が必要だ。
Claude Codeへの指示でこのフィルターパターンを活用できる:
@myorg/utils を変更します。このパッケージに依存しているパッケージを
--filter ...@myorg/utils でテストしてください。影響範囲を特定してから変更を加えるフローを作れるのが、--filterの実用的な強みだ。
Catalog機能:依存バージョンを一元管理する
pnpm 9.5で導入されたCatalog機能は、依存バージョンをpnpm-workspace.yamlで一元管理する仕組みだ。複数のパッケージが同じライブラリを使うモノレポでは、バージョンの不一致が静かに発生しやすい。Catalogはその問題を構造から解決する。
# pnpm-workspace.yaml
packages:
- "packages/*"
- "apps/*"
catalog:
react: "^18.3.0"
typescript: "^5.4.0"
zod: "^3.22.0"
catalogs:
react19:
react: "^19.0.0"
react-dom: "^19.0.0"各パッケージのpackage.jsonではcatalog:プロトコルで参照する。
{
"dependencies": {
"react": "catalog:",
"react-dom": "catalog:react19",
"zod": "catalog:"
}
}全パッケージのReactバージョンを上げたいとき、pnpm-workspace.yamlの1行を変えるだけで済む。各パッケージのpackage.jsonを個別に修正する必要がない。pnpm publish時には実際のバージョン番号に置換される。
Claude Codeへの指示でもこのパターンを活かせる:
@myorg/app に zod を追加してください。
pnpm-workspace.yaml の catalog に zod がある場合は catalog: プロトコルで、
ない場合は catalog に追加してから参照してください。Claude Code × pnpm Workspaces:CLAUDE.md とプロンプトパターン
CLAUDE.mdに書くべきworkspace規約
Claude Codeはpackage.jsonとpnpm-workspace.yamlを読んでパッケージ構成を把握できる。ただし、workspace:*と実バージョンの使い分け・ルートへのインストールの扱い・Catalogセクションの存在と使い方は、明示しないと誤操作につながる。
ルートのCLAUDE.mdに次のテンプレートを書いておくことで、これらの問題を予防できる。
## パッケージマネージャー規約
- パッケージマネージャー: pnpm workspaces
- 内部パッケージ参照は workspace:* プロトコルを使う(バージョン番号は書かない)
- npm install、yarn add は使用禁止
- ルートへの直接インストール禁止(--workspace-root が必要な場合を除く)
## パッケージ構成
- packages/ui → 共有UIコンポーネント (@myorg/ui)
- packages/utils → 共有ユーティリティ (@myorg/utils)
- apps/web → Next.jsフロントエンド
- apps/api → Expressサーバー
## よく使うコマンド
- 全パッケージビルド: pnpm --filter "@myorg/*" run build
- 開発起動: pnpm --filter "apps/*" run dev
- 特定パッケージに追加: pnpm --filter @myorg/app add <package-name>
- 依存含めビルド: pnpm --filter @myorg/app... run build頻出プロンプトパターン
内部依存追加
apps/web が @myorg/ui を使うように設定してください。
package.json の dependencies に workspace:* で追加し、pnpm install を実行してください。影響範囲のテスト
@myorg/utils を変更します。
--filter ...@myorg/utils で依存パッケージを全てテストしてください。新規パッケージ追加
packages/ に @myorg/config パッケージを追加してください。
package.json の name は "@myorg/config"、
apps/web から workspace:* プロトコルで参照するように設定してください。Claude Codeが誤った操作をした場合のほとんどは「pnpm固有のルールがCLAUDE.mdにない」ことが原因だ。明示的に書かれていれば、Claude Codeは忠実に従う。
まとめ
pnpm Workspacesの日常的な操作は3つの機能を組み合わせて成立している。pnpm-workspace.yamlでパッケージの場所を定義し、workspace:プロトコルで内部参照を管理し、--filterで必要なパッケージだけを動かす。Catalogはその上に「バージョンの一元管理」を加える機能だ。
Claude Codeとの組み合わせでは、CLAUDE.mdに「内部参照はworkspace:*」「ルートへの直接インストール禁止」「Catalogセクションの意味」を書いておくことが最初のステップになる。記述があれば、Claude Codeは依存追加から影響範囲のテストまで正確に実行できる。
まず既存プロジェクトのCLAUDE.mdにworkspace規約のセクションを追加することから始めてみてほしい。

コメント