
パッケージマネージャーとして人気を集める「pnpm」。その導入時に生成される pnpm-lock.yaml は、npmの package-lock.json やyarnの yarn.lock とは仕組みが大きく異なります。本記事では、pnpmのロックファイルの特徴やnpmとの違い、プロジェクト運用上の注意点について初心者にも分かりやすく、具体例を交えて丁寧に解説します。
目次
目次
pnpm-lock.yamlとは?
pnpm-lock.yaml
は、pnpmを使用したプロジェクトにおいて、依存関係の正確なバージョンを記録するためのロックファイルです。このファイルは、再現性のあるビルド(deterministic builds)を保証するために必要不可欠な役割を果たします。
ロックファイルとは?
ロックファイルは、開発者がインストールしたパッケージのバージョンや依存関係の情報を固定化するためのファイルです。これにより、チームの他のメンバーやCI環境でも同じ状態の依存関係を再現することができます。
たとえば、package.json
にはバージョン指定が ^1.5.0
と書かれていても、実際には 1.5.3
がインストールされていた場合、ロックファイルにはその 1.5.3
の情報が記録されます。
pnpm-lock.yamlの特徴
- YAML形式で記述されており、人間が読んでも比較的分かりやすい
- 依存関係がフラットではなくリンク構造(ハードリンク)で管理される
node_modules/
は仮想的な構造で構築され、ディスク容量の節約にもつながる.pnpm-store
に一度ダウンロードしたパッケージをキャッシュするため、高速な再インストールが可能
npmとのロックファイルの違い
npmにも package-lock.json
というロックファイルがありますが、pnpmとの間には以下のような違いがあります。
比較項目 | pnpm(pnpm-lock.yaml) | npm(package-lock.json) |
---|---|---|
ファイル形式 | YAML形式 | JSON形式 |
重複パッケージ | 同じ依存が複数箇所で必要な場合でも、バージョンごとに1つだけ保持し、各所でリンク共有される | 依存するパッケージごとに重複してインストールされることがあり、同じバージョンでも複数コピーされる |
ストレージ構造 | .pnpm-store に一元管理されたキャッシュを保存し、node_modules 内はハードリンクで仮想構造を構築。実ファイルは重複せず効率的。 | 依存パッケージはすべて node_modules にコピーされ、プロジェクトごとに物理ファイルが重複しがち。 |
ファイルサイズ | 比較的コンパクト | 大きくなりがち |
依存の再現性 | 極めて高い | 高いが、構造的にズレやすい |
ストレージ構造と重複パッケージの違いを詳しく解説
pnpmが他のパッケージマネージャーと大きく異なる点のひとつが、node_modules
の構造とストレージ戦略です。
1. .pnpm-store
によるキャッシュ管理
pnpmは、ダウンロードしたすべてのパッケージを .pnpm-store
という専用のディレクトリに保存します。これはグローバルキャッシュのような役割を持ち、複数のプロジェクトで同じパッケージを使いまわすことができます。
~/.pnpm-store
└── v3
└── files
└── sha512-...
この仕組みにより、同じ依存パッケージを別のプロジェクトでも再利用でき、ネットワークアクセスやディスク使用量が大幅に削減されます。
2. ハードリンクによる node_modules
構築
pnpmは .pnpm-store
にあるパッケージのファイルをハードリンクという仕組みで node_modules
に展開します。つまり、ファイルは物理的には1つだけで、複数の場所から同じ実体を参照しています。
- ディスク容量が節約できる
- 同じバージョンの依存パッケージを何度もインストールする必要がない
- 再現性のある構造を構築しやすい
3. 重複パッケージの扱い
npmでは、依存するモジュールごとに同じパッケージが繰り返しインストールされ、node_modules
の階層が深くなることがあります(例:A > B > lodash
、A > C > lodash
など)。
一方pnpmでは、バージョンが同じであれば1つのパッケージをすべての依存元と共有するため、同じバージョンの lodash
は1回しか保存されず、必要な場所にリンクされるだけです。
このように、pnpmのストレージ構造と重複パッケージ管理は、パフォーマンス・省容量・保守性の面で大きなメリットがあります。
実際のファイルの一部例(pnpm-lock.yaml)
lockfileVersion: 5.4
importers:
.:
dependencies:
axios: 1.5.0
packages:
/axios/1.5.0:
resolution: { integrity: sha512-xxxxxx }
dev: false
このように、どのパッケージがどのバージョンで、どこから取得されたのかが明記されています。
初心者がつまずきやすいポイントと運用上の注意点
1. pnpm-lock.yaml
を直接編集してはいけない
これはpnpmが自動生成・管理するファイルです。手動で変更すると、依存関係の整合性が崩れる原因になります。もし内容を変更したい場合は、package.json
を更新してから pnpm install
を実行しましょう。
2. チーム開発ではパッケージマネージャーを統一
プロジェクトで複数のパッケージマネージャーを使うと、node_modules/
の構造やロックファイルの整合性が保てず、トラブルの原因になります。
.npmrc
を使ってバージョンを固定すると安心です:
package-manager=pnpm@8.15.3
3. CI/CD環境でもpnpmを使用
CIツール(GitHub Actions や GitLab CIなど)では、必ず pnpm install --frozen-lockfile
を使用しましょう。これにより、ロックファイルと package.json
の不整合を防ぎ、常に同じ依存関係でデプロイできます。
pnpm install --frozen-lockfile
この --frozen-lockfile
オプションは、pnpm-lock.yaml
の内容を絶対に変更しないことを保証するためのものです。具体的には、以下のような動作になります:
package.json
に書かれた依存とpnpm-lock.yaml
の内容が一致していない場合、エラーを出してインストールを中断します。- ロックファイルが存在しない場合や、古い内容のままで
package.json
が更新されている場合も、失敗します。
これにより、本番環境やCI環境で依存関係が書き換わることを防ぎ、完全に同一の環境構築を実現できます。
※ 開発中に意図的に依存を更新する場合は、--frozen-lockfile
を外して pnpm install
を実行し、その後ロックファイルを確認・コミットしましょう。
4. Gitに必ずコミットしよう
pnpm-lock.yaml
はチームの開発環境を保つための重要なファイルです。.gitignore
に含めず、必ずリポジトリにコミットしてください。
補足:pnpmとnpmの速度・容量の違い
pnpmは依存関係を「ハードリンク」で管理するため、ディスク容量を大幅に節約できます。実際に同じ依存を複数のプロジェクトで使っても、物理的には1つのファイルしか存在しません。また、キャッシュを活かしてインストール速度も非常に高速です。
体感例
# 初回(キャッシュなし)
pnpm install → 約8秒
npm install → 約25秒
# 2回目(キャッシュあり)
pnpm install → 約1秒
npm install → 約10秒
まとめ:pnpm-lock.yamlはpnpmの強みを支える重要ファイル
pnpm-lock.yaml
はpnpm特有の依存管理を実現するための中核ファイルであり、npmとは大きく構造が異なります。再現性・パフォーマンス・ストレージ効率を向上させる一方で、運用においてはツールの統一やCI設定の徹底が不可欠です。
初心者であっても、基本的なルール(手動で編集しない・Gitで管理する・CIで活用する)を押さえておけば安心して使えます。pnpmの特性を正しく理解して、スムーズなチーム開発につなげましょう。