フロントエンド - ビルド・ツール

pnpm ぴーえぬぴーえむ

パッケージマネージャーNode.jsnpmYarnモノレポシンボリックリンク
pnpmについて教えて

簡単に言うとこんな感じ!

JavaScriptのライブラリ管理ツールなんだけど、npmやYarnより賢くてディスク節約上手なやつだよ!同じライブラリは一か所だけ保存して、複数プロジェクトで使い回す仕組みになってるから、インストールが速くて容量もぐっと減るってこと!


pnpmとは

pnpm(Performant npm)は、Node.js向けのパッケージマネージャーのひとつで、npmやYarnと同じくJavaScript/TypeScriptプロジェクトで使用する外部ライブラリ(パッケージ)を管理するツールです。2016年ごろに登場し、既存ツールの「ディスクを無駄に使いすぎる」「インストールが遅い」という課題を解決するために設計されました。

最大の特徴はコンテンツアドレッサブルストアという仕組みで、マシン上の1か所にパッケージを集中管理し、各プロジェクトからはシンボリックリンク(ショートカット)で参照させます。つまり同じバージョンのライブラリを何十のプロジェクトで使っていても、実体ファイルはただ1つ。ディスク使用量が劇的に減ります。

また、モノレポ(monorepo)と呼ばれる「1つのリポジトリで複数プロジェクトを管理するスタイル」との相性が非常によく、大規模なフロントエンド開発現場での採用が急速に広がっています。Vite・Turborepo・Nx など現代的なツールチェーンでも公式サポートされています。


pnpmの仕組みと特徴

npmやYarnとの根本的な違い

従来のnpmやYarnは、プロジェクトごとに node_modules フォルダへパッケージをコピーしていました。pnpmはコピーの代わりにハードリンク+シンボリックリンクを使います。

【npm / Yarn の場合】
プロジェクトA/node_modules/react/  ← 実体ファイル(100MB)
プロジェクトB/node_modules/react/  ← また実体ファイル(100MB)
プロジェクトC/node_modules/react/  ← また実体ファイル(100MB)
合計: 300MB 消費

【pnpm の場合】
~/.pnpm-store/react@18.2.0/       ← 実体ファイル(100MB)1か所のみ
プロジェクトA/node_modules/react  → ストアへのリンク
プロジェクトB/node_modules/react  → ストアへのリンク
プロジェクトC/node_modules/react  → ストアへのリンク
合計: 100MB + リンクのみ

主な特長まとめ

特長内容
高速インストールファイルコピーが不要なのでインストールが速い
ディスク節約同一パッケージは1か所に保存し使い回す
厳格な依存解決宣言していないパッケージへはアクセス不可(ゴースト依存防止)
モノレポ対応Workspaces機能で複数パッケージを一元管理
npm互換package.json・lockfileの形式は互換性あり

「ゴースト依存」って何?

npmでは node_modules がフラットな構造になるため、package.jsonに書いていないパッケージも誤ってimportできてしまうことがあります(ゴースト依存・幽霊依存)。pnpmは厳格なシンボリックリンク構造で宣言済みパッケージしかアクセスできないようにし、このバグを防ぎます。


歴史と背景

  • 2016年 — Zoltan Koczanが「npmのディスク無駄遣い問題」を解決するためpnpmをOSSとして公開
  • 2018年頃 — Workspaces機能が追加され、モノレポ管理ツールとして注目を集める
  • 2020年 — v5リリース。コンテンツアドレッサブルストアの仕組みが現在の形に確立
  • 2021年 — v6リリース。npmと同等の使い勝手を実現しつつ大幅な高速化
  • 2022年 — v7リリース。Node.js Corepackへの統合が進み、インストール不要で使えるケースが増加。ViteやTurborepoが公式サポート
  • 2023〜現在 — v8・v9リリース。エンタープライズ・大規模フロントエンドでのデファクト化が進行中

npm・Yarn・pnpm 三者比較

機能比較テーブル

比較項目npmYarn v1Yarn Berry (v2+)pnpm
ディスク効率△ 低い△ 低い◯ ZIPキャッシュ◎ 最も高い
インストール速度△ 遅め○ 速い◎ 最速級◎ 最速級
モノレポ対応△ 限定的◯ あり◎ 充実◎ 充実
ゴースト依存防止✗ なし✗ なし◯ あり◎ 厳格
学習コスト◎ 低い○ 低い△ 高い○ 低い
npm互換性◎ 完全◎ ほぼ完全△ 独自形式あり◯ ほぼ完全

パッケージマネージャーの構造図

パッケージマネージャーの node_modules 構造比較 npm / Yarn v1 プロジェクトA node_modules/react ✦ プロジェクトB node_modules/react ✦ プロジェクトC node_modules/react ✦ ✦ = 実体ファイルをコピー ディスク: 3倍消費 pnpm ~/.pnpm-store(集中ストア) react@18.2.0 ← 実体1つ lodash@4.17.21 ← 実体1つ typescript@5.x ← 実体1つ プロジェクトA プロジェクトB プロジェクトC 点線 = シンボリックリンク(参照のみ) ディスク: 1倍(節約!) 宣言外パッケージへのアクセス: ブロック

基本的なコマンド対応

# パッケージのインストール
npm install          →  pnpm install
npm install react    →  pnpm add react
npm install -D vite  →  pnpm add -D vite

# スクリプト実行
npm run build        →  pnpm run build  または  pnpm build

# モノレポ全体に対して実行
(npm workspaces)   →  pnpm -r run build

# ストアの場所を確認
                        pnpm store path

関連用語

  • npm — Node.jsの標準パッケージマネージャー。pnpmが解決しようとした課題の元
  • Yarn — Facebookが開発したnpmの代替パッケージマネージャー
  • Node.js — JavaScriptをサーバーサイドで動かすランタイム環境
  • モノレポ — 複数プロジェクトを1つのリポジトリで管理する開発スタイル
  • package.json — Node.jsプロジェクトの依存パッケージや設定を記述するファイル
  • Vite — 高速なフロントエンドビルドツール。pnpmとの相性が良い
  • Turborepo — モノレポ向けの高速ビルドシステム。pnpm workspacesと組み合わせて使われる
  • シンボリックリンク — ファイルやディレクトリへの「ショートカット」。pnpmの中核技術