🔄
【npm×pnpm】パッケージマネージャ混在の落とし穴と解決法
はじめに
フロントエンド開発を進めていると、プロジェクトの移行やCI/CDの環境により、個人のローカル環境ごとに npm installやpnpm install を使ってしまい、結果として混在してしまうケースがあります。私自身も、チームでの開発中に両者が混在した環境に遭遇し、ビルドエラーや依存関係の不一致に悩まされました。本記事では、npmとpnpmが混在した場合に発生する問題と、解決策を整理します。
対象者
- フロントエンドエンジニア
- npmからpnpmへの移行を検討している方
- チーム開発でnpmとpnpmが混在してしまっている方
npmとpnpmの概要
npmとは
概要
- Node.jsに標準で付属するパッケージマネージャ
- 豊富なエコシステムと公式サポートが強み
- 多くのチュートリアルや記事で前提として使われているため、学習コストが低い
メリット
- 標準ツールとして環境依存が少ない
- サポート情報や記事が圧倒的に多い
- 新規学習者にとって理解しやすい
pnpmとは
概要
- ディスク効率と高速性を重視した次世代のパッケージマネージャ
- シンボリックリンクを活用し、同じ依存関係を複数回保存しない
- モノレポ開発や大規模プロジェクトで人気が高まっている
メリット
- インストール速度がnpmより速いケースが多い
- ディスク使用量を大幅に削減できる
- peerDependenciesを厳格に扱うため、潜在的な不具合を早期に発見可能
npmとpnpm、どちらを選ぶべきか
- 小規模・学習目的・公式に沿った環境: npmがおすすめ
- モノレポ・CI/CDの効率化・大規模開発: pnpmがおすすめ
混在すると何が起きるのか
1. lockfileの不一致
- npmは
package-lock.json、pnpmはpnpm-lock.yamlを使用 - どちらか一方を更新しても、もう一方は無視されるため、CI/CDで別の依存バージョンが入る
2. node_modulesの構造が違う
- npm: フラットに依存関係を配置
- pnpm: シンボリックリンクで効率的に配置
- 両方を行き来すると、依存解決が壊れるケースがある
3. peerDependenciesの扱いの差
- pnpmはpeerDependenciesに厳格で、npmでは通っていたビルドがpnpmでは失敗することも
4. CI/CDの挙動不一致
- ローカルでは動いていたのに、CI環境ではエラーになる
- 特にDocker環境で「キャッシュが効かない」「依存が足りない」といった事象が発生
解決策
1. パッケージマネージャを明示的に固定する
-
package.jsonに以下を追加{ "packageManager": "pnpm@9.12.0" } -
Node.js v16以降ではCorepackを使って自動的に正しいバージョンを利用可能
2. CI/CD環境の統一
-
GitHub ActionsやVercelなどのCI/CDで、必ずpnpmをインストールして利用
-
例: GitHub Actions
- uses: pnpm/action-setup@v2 with: version: 9.12.0
3. 古いlockfileの削除
-
package-lock.jsonを削除し、pnpm-lock.yamlに統一 - node_modules を削除して再インストール
4. 誤使用を防止する仕組み作り
- Huskyやpre-commitフックで
npm installを禁止する - READMEや開発ガイドラインで明記する
以上です。
おわりに
npmとpnpmはどちらも便利ですが、混在させると依存関係の不一致でデプロイが失敗するなどの開発効率を大きく損なう可能性があることを学びました。
もしも似た状況にあるなら、ぜひともプロジェクトのパッケージマネージャを統一することをおすすめします。本記事がそういった方の問題解決の糸口になれば幸いです。
株式会社ONE WEDGE
【Serverlessで世の中をもっと楽しく】
ONE WEDGEはServerlessシステム開発を中核技術としてWeb系システム開発、AWS/GCPを利用した業務システム・サービス開発、PWAを用いたモバイル開発、Alexaスキル開発など、元気と技術力を武器にお客様に真摯に向き合う価値創造企業です。
Discussion