TL;DR

npm と同じ役割を持つパッケージマネージャ。依存パッケージを 1 か所のストアにまとめて置き、各プロジェクトからはリンクで参照するので、ディスクを節約でき、インストールも速い。

なぜ必要か

npm は同じ依存パッケージをプロジェクトごとに別々にコピーする。また、npm や Yarn Classic はすべてのパッケージを node_modules の直下に巻き上げるので、コードが宣言していないパッケージを import できてしまう。

仕組み

pnpm は依存パッケージを内容でアドレスを決めるストア(content-addressable store)に置き、プロジェクトからはハードリンクか copy-on-write のクローンで参照する。同じパッケージの別のバージョンでも、中身が同じファイルは共有するので、変わったファイルだけが追加される。

インストールでは、依存関係の解決、取得、書き込みをすべてのパッケージでそろえて進めず、準備のできたパッケージから次の段階に進める。

node_modules の直下には、そのプロジェクトが直接依存するパッケージだけをシンボリックリンクで置き、依存関係のツリー全体は node_modules/.pnpm に置く。

注意点

シンボリックリンクをうまく扱えないツールでは、nodeLinker を hoisted にすると npm と同じような配置にできる。また、モノレポで使うときは pnpm-workspace.yaml を別に作る必要があり、Workspace 内の別のパッケージを依存に含めるには "workspace:*" のような接頭辞を付ける。

関連

出典