【ピーエヌピーエム】

pnpm とは?

最終更新:
💡 同じ部品は倉庫に1つだけ。各プロジェクトには「通路」をつなぐ倹約家

Node.jsのパッケージマネージャーの1つ。パッケージのファイルを1か所のストアに保存してハードリンクで使い回し、シンボリックリンクで依存関係を厳密に区切ったnode_modulesを作る。

📌 このページのポイント
npm vs pnpm: パッケージの保存方法 npm Project A パッケージA 100MB パッケージB 50MB Project B パッケージA 100MB パッケージB 50MB 合計: 300MB (コピー) pnpm グローバルストア パッケージA 100MB パッケージB 50MB Project A ハードリンク Project B ハードリンク 合計: 150MB (共有) x2 プロジェクトごとにコピー 同じ版・同じドライブなら半分に
pnpmのハードリンクによるディスク節約のイメージ
ひよこ ひよこ
pnpmってnpmと何が違うの?名前が似てるけど…
ペンギン先生 ペンギン先生
いちばんの違いはパッケージの置き方だよ。npmはプロジェクトごとのnode_modulesにファイルを書き出すけど、pnpmはファイルを1か所のストアに保存して、各プロジェクトからはハードリンクで参照するんだ
ひよこ ひよこ
ハードリンクって何?
ペンギン先生 ペンギン先生
1つのファイルの中身に、別の場所からも名前を付けてたどれるようにする仕組みだよ。コピーではないから、同じバージョンの100MBのパッケージを10個のプロジェクトで使っても、中身は基本的に1つ分で済むんだ。ただしハードリンクは同じファイルシステムの中でしか作れないから、ストアとプロジェクトが別のドライブにあるとコピーになるよ
ひよこ ひよこ
速さはどのくらい違うの?
ペンギン先生 ペンギン先生
pnpmの公式ベンチマークでは、キャッシュなしの新規インストールから何も変わっていない状態での再実行まで、計測した全シナリオでnpmより速かったよ。でも差の大きさはプロジェクトや環境で変わるから、自分のプロジェクトのCIで測ってみるのが確実だね
ひよこ ひよこ
幽霊依存って何?怖い名前だけど…
ペンギン先生 ペンギン先生
npmのフラットなnode_modulesでは、package.jsonに書いていない間接的な依存パッケージもプロジェクトから読み込めてしまうことがあるんだ。依存先の都合でそのパッケージが外れると、ある日突然動かなくなるよ。pnpmはnode_modulesの直下に自分で入れたパッケージだけを置くから、書き忘れに早く気づけるんだ
ひよこ ひよこ
おもしろい!モノレポでも使えるの?
ペンギン先生 ペンギン先生
使えるよ。pnpmはワークスペース機能を標準で持っていて、pnpm-workspace.yamlで対象のフォルダを指定するんだ。「workspace:」という書き方で、レジストリではなく手元のパッケージを確実に参照させることもできるよ
もっと詳しく知りたい人へ

pnpmに切り替えたら、今まで動いていたプロジェクトがエラーになりました。なぜですか?

多くの場合、package.jsonに書いていないパッケージをコードや依存先が使っている(幽霊依存)ことが原因です。npmのフラットなnode_modulesでは偶然読み込めていたものが、pnpmでは見えなくなるためです。公式FAQでは、足りない依存をpackage.jsonに追加する、問題のある依存先を.pnpmfileのフックで補う、またはnodeLinkerの設定でnpmのような巻き上げ型(hoisted)のnode_modulesに切り替える、といった対処が案内されています。

ペンギン
まとめ:ざっくりこれだけ覚えればOK!
「pnpm」って出てきたら「同じパッケージのファイルを使い回して、ディスクと時間を節約するNode.jsのパッケージマネージャー」と思えればだいたいOK!
📖 おまけ:英語の意味
「performant npm」 = 高性能なnpm
💬 公式FAQでは「pnpmはperformant npmの略」と説明されていて、名付け親はRico Sta. Cruzさんだよ

参考資料

← 用語集にもどる