📄
概念 📚 beginner-stepup

パッケージ管理(pnpm workspace)

pnpm・package.json・依存関係の仕組みを理解し、pnpm workspaceを使ったモノリポ構成を使いこなす

pnpmはNode.jsのパッケージマネージャーで、Pythonの pip に相当する。このカリキュラムでは npm の代わりに pnpm を使う。理由は2つ:インストールが高速・ディスク使用量が少ない、そして workspace(モノリポ)機能が標準で使えるため。

pnpm の基本コマンド

pnpm install                    # package.jsonの全依存関係をインストール
pnpm add react                  # reactを追加
pnpm add -D typescript          # TypeScriptをdevDependenciesに追加
pnpm remove lodash              # パッケージを削除

pnpm dev                        # scripts.devを実行
pnpm build                      # scripts.buildを実行
pnpm test                       # テストを実行

npm の代わりに pnpm と書くだけで、ほぼ同じように使える。

package.json の構造

{
  "name": "api",
  "version": "0.1.0",
  "scripts": {
    "dev": "tsx watch src/index.ts",
    "build": "tsc -p tsconfig.build.json",
    "typecheck": "tsc --noEmit",
    "db:push": "drizzle-kit push"
  },
  "dependencies": {
    "hono": "^4.9.0"
  },
  "devDependencies": {
    "typescript": "^5.9.0",
    "tsx": "^4.19.2"
  }
}

dependencies: アプリの実行に必要なパッケージ
devDependencies: 開発・ビルド時のみ使うパッケージ(TypeScript等)
scripts: pnpm dev のように呼び出せるコマンドの定義

pnpm workspace(モノリポ)

このカリキュラムのリポジトリは pnpm workspace を使ったモノリポ構成になっている:

fullstack_typescript_curriculum/
├── pnpm-workspace.yaml   workspaceの設定
├── package.json          ルートのパッケージ設定(全体のスクリプト)
├── web/                  フロントエンド(React + Vite)
│   └── package.json
└── api/                  バックエンド(Hono)
    └── package.json
# pnpm-workspace.yaml
packages:
  - "web"
  - "api"

1つのリポジトリに web/api/ という2つの独立したパッケージが共存している。これが**モノリポ(monorepo)**と呼ばれる構成。

ルートからの一括操作

ルートディレクトリから web/api/ の両方を操作できる:

# ルートで pnpm dev を実行すると web と api が同時に起動
pnpm dev

# 特定のワークスペースだけ操作する
pnpm --filter api add hono
pnpm --filter web add react-router-dom

# 全ワークスペースに対して実行
pnpm -r typecheck    # web と api 両方で型チェック

node_modules とロックファイル

fullstack_typescript_curriculum/
├── node_modules/     ← pnpm が一元管理(gitignore する)
├── pnpm-lock.yaml    ← バージョンのロックファイル(gitに含める)
├── web/
│   └── node_modules → ../../node_modules(シンボリックリンク)
└── api/
    └── node_modules → ../../node_modules(シンボリックリンク)

pnpm はパッケージを一箇所(~/.pnpm-store)に保存し、シンボリックリンクで参照する。同じパッケージを複数プロジェクトで使っても1回しかダウンロードしない。

pnpm-lock.yaml はインストールした各パッケージの正確なバージョンを記録する。これをGitにコミットすることでチーム全員が同じバージョンを使えることが保証される。

セマンティックバージョニング

バージョン番号 4.9.0メジャー.マイナー.パッチ の意味:

  • パッチ(4.9.0 → 4.9.1): バグ修正のみ
  • マイナー(4.9.0 → 4.10.0): 新機能追加、後方互換あり
  • メジャー(4.9.0 → 5.0.0): 破壊的変更、移行作業が必要

^4.9.0(キャレット): メジャーを固定、マイナー・パッチは最新を許可

参考リソース


確認クイズ

Q1. pnpm が npm より優れている点を2つ挙げよ。

正解: インストールが高速でディスク使用量が少ない、workspace(モノリポ)機能が標準で使える

解説: pnpm はパッケージをグローバルストア(~/.pnpm-store)に一度だけ保存し、各プロジェクトからシンボリックリンクで参照する。そのためnpmのように同じパッケージを何度もダウンロードせず、ディスクを節約できる。

Q2. pnpm add -D typescript を実行すると、package.json のどのフィールドにtypescriptが追加されるか。A. dependencies B. devDependencies C. scripts D. peerDependencies

正解: B

解説: -D フラグは devDependencies への追加を指定する。TypeScriptはコンパイル時のみ使用し、実行環境では不要なため devDependencies に入れるのが正しい。本番サーバーで不要なパッケージを dependencies に入れるとデプロイパッケージが肥大化する。

Q3. pnpm-workspace.yaml はどのような役割を持つファイルか。

正解: モノリポ内のどのディレクトリをワークスペース(個別パッケージ)として認識するかを定義するファイル。

解説: packages: フィールドにディレクトリ名を列挙することで、ルートの pnpm が各パッケージを認識できるようになる。これにより --filter による個別操作や -r による全体一括操作が可能になる。

Q4. モノリポ(monorepo)とはどのような構成を指すか。

正解: 1つのリポジトリに複数の独立したパッケージ(例:web と api)が共存する構成。

解説: モノリポにすることで、フロントエンドとバックエンドを同じリポジトリで管理でき、依存関係の共有やルートからの一括操作が容易になる。pnpm workspace はこの構成を低コストで実現する。

Q5. pnpm --filter api add hono コマンドは何をするか。

正解: api ワークスペースだけに hono パッケージを追加する。

解説: --filter オプションを使うと、ルートディレクトリにいながら特定のワークスペースのみを対象に操作できる。web/ に移動して pnpm add するのと同等だが、ルートから統一的に操作できる利点がある。

Q6. pnpm -r typecheck コマンドが実行すること、および -r フラグの意味を答えよ。

正解: -r は全ワークスペース(recursive)を対象にするフラグ。webapi 両方の scripts.typecheck を実行する。

解説: -r フラグを使うと pnpm-workspace.yaml で定義された全パッケージに対して同じコマンドを一斉実行できる。CIで全パッケージの型チェックやテストを実行するときに便利。

Q7. pnpm において node_modules はどのように管理されるか。A. 各パッケージに個別に保存される B. グローバルストアに1か所保存しシンボリックリンクで参照する C. クラウドに保存される D. package.json に埋め込まれる

正解: B

解説: pnpm は ~/.pnpm-store にパッケージを一元保存し、各プロジェクトの node_modules からシンボリックリンクで参照する。同一パッケージを複数プロジェクトで使っても実体は1つのためディスク節約になる。

Q8. pnpm-lock.yaml をGitにコミットすべき理由を答えよ。

正解: チーム全員が同じバージョンのパッケージを使えることを保証するため。

解説: ロックファイルがなければ pnpm install の実行タイミングによってインストールされるパッケージのバージョンが異なる可能性がある。ロックファイルをコミットすることで「自分のPCでは動くが他の人の環境では動かない」問題を防ぐ。

Q9. バージョン ^4.9.0 のキャレット(^)は何を意味するか。

正解: メジャーバージョンを固定し、マイナーとパッチは最新を許可する。つまり 4.x.x の最新が許可される(5.0.0 は対象外)。

解説: セマンティックバージョニングではメジャー変更が破壊的変更を意味するため、キャレットを使うことで安全な範囲で自動更新できる。ただし依存関係の完全固定が必要な場合はロックファイルと組み合わせて使う。

Q10. 4.9.0 → 5.0.0 のようなメジャーバージョンアップが行われる場合、何が起きる可能性があるか。

正解: 破壊的変更(breaking change)が含まれており、既存のコードが動かなくなる可能性がある。移行作業が必要になる。

解説: セマンティックバージョニングの規約では、メジャーバージョンアップは後方互換性のない変更を含むことを示す。APIの引数変更・関数の廃止・動作の変更などが含まれるため、アップグレード前にリリースノートやマイグレーションガイドを確認する必要がある。

生きているコード

本ドキュメントで扱ったパターンの完全な動作コードは、メンター側リポジトリの参照ブランチで確認できます。

  • 対応 Week: W1
  • 参照ブランチ:
  • W1: reference/week-1
  • 対応 checklist 項目: (直接対応なし)

ブランチの作り方・見方は b00-curriculum-map を参照してください。

📚 beginner-stepup 全 53 章
導入編 13 章 ● この編を閲覧中
  1. 1. 📄Web とは何か
  2. 2. 📄URL を打ってから画面が表示されるまで
  3. 3. 📄ネットワーク基礎(TCP/IP・DNS・HTTPS)
  4. 4. 📄【発展】物理層から通信が成立するまで(電力・Ethernet・Wi-Fi・Bluetooth)
  5. 5. 📄WSL2・Docker セットアップ詳細(Windows 向け)
  6. 6. 📄環境構築の段階的導入(macOS / Windows)
  7. 7. 📄カリキュラム全体マップ(Week × 教材 × 参照ブランチ × 要求チェックリスト)
  8. 8. 📄このカリキュラムの使い方(SQL・Python・Dify経験者向け)
  9. 9. 📄シェル・ターミナル基礎
  10. 10. 📄Windows で完全にゼロから始める開発環境構築(Week 1)
  11. 11. 📄Git基礎
  12. 12. 📄GitHubワークフロー
  13. 13. 📄パッケージ管理(pnpm workspace)
応用編 16 章
  1. 1. 📄AWSインフラ基礎
  2. 2. 📄AWS Budget Alert の設定(Month 5 Week 17)
  3. 3. 📄環境変数管理
  4. 4. 📄Bastion EC2 と SSH ProxyJump(Month 5 Week 18)
  5. 5. 📄CI/CD基礎
  6. 6. 📄ECR への Docker イメージ push と App EC2 デプロイ(Month 5 Week 19)
  7. 7. 📄テスト設計の基本
  8. 8. 📄CloudFront + S3 + ALB で公開する(Month 5 Week 20)
  9. 9. 📄CLAUDE.md・プロジェクト設定
  10. 10. 📄PR レビュー 5 観点ルーブリック(全 Week 共通)
  11. 11. 📄タスク分解・仕様の書き方
  12. 12. 📄Playwright で E2E テスト(Month 6 Week 22)
  13. 13. 📄生成コードのレビュー・デバッグの勘所
  14. 14. 📄Trivy で脆弱性スキャン(Month 6 Week 23)
  15. 15. 📄CloudWatch Logs の読み方と運用(Month 6 Week 23)
  16. 16. 📄PDF ポートフォリオの自動生成(Month 6 Week 24)