Back

pnpm入門:npmとYarnより高速な代替手段

pnpm入門:npmとYarnより高速な代替手段

CI/CDパイプラインが依存関係のインストールに数分かかるのを見たことがあるなら、あるいはプロジェクト間で重複するパッケージによって開発マシンのディスク容量に苦労したことがあるなら、それはまさにpnpmが解決するために設計された問題です。この高性能なパッケージマネージャーは、依存関係管理に対して根本的に異なるアプローチを提供し、インストール時間を2〜3倍短縮し、ディスク使用量を約50%削減できます。

重要なポイント

  • pnpmはコンテンツアドレス可能なストアとハードリンクを使用して、プロジェクト間での重複パッケージを排除
  • 厳格な依存関係解決により、ファントム依存関係を防ぎ、本番環境前にエラーを検出
  • npmと比較してインストール速度が2〜3倍向上し、ディスク使用量が50%削減
  • 組み込みのワークスペースサポートにより、モノレポアーキテクチャに最適

pnpmが異なる理由

npmやYarnがプロジェクト間でパッケージを重複させるのとは異なり、pnpmはコンテンツアドレス可能なストアとハードリンクを使用して、依存関係をグローバルに共有します。複数のプロジェクトでExpressをインストールする場合、npmは各node_modulesフォルダに個別のコピーを作成します。pnpmは~/.pnpm-storeに一度だけ保存し、その単一のコピーへのハードリンクを作成することで、プロジェクト間の完全な分離を維持しながら、ディスク使用量を劇的に削減します。

このアーキテクチャは「ファントム依存関係」も防ぎます。これは、package.jsonにリストされていないパッケージをコードが誤ってインポートできてしまう一般的な問題です。pnpmの厳格なNode.jsモジュール解決により、依存関係が明示的に宣言されていない場合、コードはそれにアクセスできず、本番環境に到達する前にエラーを検出します。

インストールとセットアップ

Node.js 16.13以降の場合、推奨されるインストール方法はCorepackを使用します:

corepack enable
corepack prepare pnpm@latest --activate

または、npm経由でインストール:

npm install -g pnpm

日常開発に必須のコマンド

pnpmのコアコマンドは、npmの使い慣れた構文を踏襲しながら、パフォーマンスの最適化を追加しています:

pnpm add express          # 本番依存関係を追加
pnpm add -D typescript    # 開発依存関係を追加
pnpm remove lodash       # パッケージを削除
pnpm update             # すべての依存関係を更新
pnpm run build         # package.jsonからスクリプトを実行

pnpm storeコマンドは、グローバルパッケージキャッシュを管理するためのユニークな機能を提供します:

pnpm store status      # ストアの健全性をチェック
pnpm store prune      # 参照されていないパッケージを削除

モダンプロジェクトのための設定

チームのためにpnpmの動作を設定する.npmrcファイルを作成します:

strict-peer-dependencies=true
auto-install-peers=true
prefer-offline=true

これらの設定は、ピア依存関係の要件を強制し、ピア依存関係を自動的にインストールし(Node.js 16+)、インストールを高速化するためにキャッシュされたパッケージを優先します。

モノレポのためのワークスペース設定

モノレポプロジェクトの場合、pnpmのワークスペースサポートは複数のパッケージの管理に優れています。pnpm-workspace.yamlファイルを作成します:

packages:
  - 'packages/*'
  - 'apps/*'

package.jsonworkspace:プロトコルを使用してワークスペースパッケージをリンクします:

{
  "dependencies": {
    "@myapp/shared": "workspace:*",
    "@myapp/ui": "workspace:^1.0.0"
  }
}

すべてのワークスペースパッケージでコマンドを実行:

pnpm -r build                  # すべてのパッケージをビルド
pnpm --filter @myapp/api dev   # 特定のパッケージでdevスクリプトを実行

CI/CDの最適化

GitHub Actionsの場合、Node.js 22 LTSで公式pnpmアクションを使用します:

- uses: pnpm/action-setup@v4
  with:
    version: 9
- uses: actions/setup-node@v4
  with:
    node-version: 22
    cache: 'pnpm'
- run: pnpm install --frozen-lockfile
- run: pnpm test

GitLab CIの場合、CI/CD最適化を最大化するためにキャッシングを設定します:

image: node:22

before_script:
  - corepack enable
  - corepack prepare pnpm@latest --activate

cache:
  key: pnpm-store-$CI_COMMIT_REF_SLUG
  paths:
    - .pnpm-store

install:
  script:
    - pnpm config set store-dir .pnpm-store
    - pnpm install --frozen-lockfile

--frozen-lockfileフラグは、pnpm-lock.yamlpackage.jsonと一致しない場合に失敗することで再現可能なビルドを保証し、開発環境と本番環境間のドリフトを防ぎます。

実践でのパフォーマンス

npmから移行するチームは、pnpmの効率的なリンク戦略により、通常インストール速度が2〜3倍向上します。500の依存関係を持つ中規模プロジェクトでは、npmで60秒かかるところが、pnpmではわずか20〜25秒で済むかもしれません。ディスクの節約はさらに劇的で、複数のプロジェクトに取り組む開発者は、重複パッケージが排除されることで5〜10GBのスペースを取り戻すことがよくあります。

まとめ

pnpmは、段階的な改善ではなく革新的なアーキテクチャを通じて、より高速で効率的な依存関係管理の約束を果たしています。その厳格な依存関係解決は早期にエラーを検出し、ワークスペース設定機能はモダンなモノレポアーキテクチャに最適です。CI/CDパイプラインの最適化や複雑なフルスタックアプリケーションの管理において、pnpmは既存のnpmエコシステムとの互換性を犠牲にすることなく、開発チームが必要とするパフォーマンスと信頼性を提供します。

よくある質問

pnpmはデフォルトで厳格なピア依存関係解決を強制します。設定でauto-install-peersを有効にしない限り、ピア依存関係を自動的にインストールしません。これによりバージョンの競合を防ぎ、プロジェクトが必要なすべての依存関係を明示的に宣言することを保証します。

はい、pnpmはnpmおよびYarnプロジェクトと完全に互換性があります。プロジェクトディレクトリでpnpm importを実行するだけで、既存のロックファイルからpnpm-lock.yamlファイルが生成されます。すべてのnpmスクリプトとpackage.json設定は変更なしで動作します。

パッケージはプロジェクトからアンインストールした後もグローバルストアに残ります。これにより、後で必要になった場合に即座に再インストールできます。定期的にpnpm store pruneを実行して、参照されていないパッケージを削除し、ディスクスペースを解放してください。

もちろんです。pnpmは本番環境対応で、大手企業でも使用されています。本番環境ではpnpm install --frozen-lockfileを使用して、正確な依存関係バージョンを保証してください。決定論的なインストールと厳格な依存関係解決により、従来のパッケージマネージャーよりもデプロイの信頼性が実際に向上します。

Understand every bug

Uncover frustrations, understand bugs and fix slowdowns like never before with OpenReplay — the open-source session replay tool for developers. Self-host it in minutes, and have complete control over your customer data. Check our GitHub repo and join the thousands of developers in our community.

OpenReplay