PNPM で推移的依存関係をアップグレードする方法:セキュリティ脆弱性を修正しつつ破壊を防ぐ
セキュリティ脆弱性の修正は、特に推移的依存関係が関わる場合、イライラすることがあります。直接の依存関係に影響を与えずに、それらをアップグレードする方法を学びましょう。
近年、セキュリティ脆弱性はソフトウェア開発における一般的な問題です。幸いなことに、GitHub Dependabot のようなツールがあり、依存関係を自動検出とプルリクエストで最新の状態に保つ手助けをしてくれます。

しかし、期待通りに機能しないこともあります。一部の依存関係が推移的であるため、これらのツールにとってアップグレードは困難なタスクとなる可能性があります。なぜなら、変更の影響や競合が発生した場合にどのような判断をすべきかを理解していないからです。このような場合、手動で対応する必要があります。
機能しない方法
pnpm upのような公式のコマンドはpnpm-lock.yamlファイルを混乱させてしまいます。この記事を書いている時点で依然として開かれている問題があります。- 目的の推移的依存関係を持つ直接の依存関係の最新バージョンをインストールしても機能しないかもしれません。直接の依存関係がバージョン定義を更新していない場合、
pnpm-lock.yamlファイルで解決およびロックされているため、推移的依存関係はアップグレードされません。
解決策
overrides フィールド は、特定のバージョン解決を上書きすることができる PNPM の強力な機能です。この機能を使用して推移的依存関係をアップグレードし、変更を可能な限り最小限に抑えます。
例として、上記の Dependabot の警告を使用しましょう。follow-redirects パッケージにセキュリティ脆弱性があり、修正されたバージョンが 1.15.6 です。しかし、直接の依存関係である gatsby が axios を使用しており、これが [email protected] に依存しています。
手順 1: 推移的依存関係を見つける
推移的依存関係を見つける方法はたくさんありますが、一番簡単な方法をお勧めします。それは pnpm-lock.yaml ファイルを検索する方法です。
「pnpm why」はどう?
pnpm why <package> コマンドは確かに便利です。しかし、このケースでは混乱させるかもしれません。例えば、pnpm why follow-redirects を実行したとき、出力の一部は次のようになります:
実際には、pnpm-lock.yaml ファイルに follow-redirects の解決は一つしかありません。pnpm why コマンドは、同じバージョンのパッケージに依存している複数のパスを表示するかもしれません。
手順 2: overrides を追加する
最も簡単なケースは、pnpm-lock.yaml ファイルに一つの解決しかない場合です。この場合、package.json ファイルに直接オーバーライドを追加できます:
ワークスペースにいる場合は、ワークスペースのルート package.json ファイルにオーバーライドを追加する必要があります。
手順 3: 変更を適用する
pnpm install を実行して変更を適用します。pnpm-lock.yaml ファイルで follow-redirects パッケージが 1.15.6 に最小限の変更でアップグレードされたことが確認できます。
次に、package.json ファイルから overrides フィールドを削除してクリーンに保ちます。そして再び pnpm install を実行し、overrides フィールドなしでも変更が適用できることを確認します。
トラブルシューティング
上記の手順は理想的なケースです。すべてが予定通りに進むとは限りません。ここで、トラブルシューティングのためのいくつかのヒントを紹介します:
「overrides」フィールドを削除した後にバージョンが戻る
依存パッケージに固定バージョンや、目的のバージョンを含まない範囲が設定されている場合にこの問題が発生することがあります。依存パッケージ、つまりこのケースでは axios の package.json ファイルを確認して、この問題が該当するか確認してください。
該当する場合は、依存パッケージがバージョン定義をアップグレードするまで package.json ファイルに overrides フィールドを保持する必要があります。
推移的依存関係に複数の解決が存在する
プロジェクトが成長するにつれて、pnpm-lock.yaml ファイルに同じパッケージの複数の解決が浮上することがあります。たとえば、同じパッケージ foo の 2 つのメジャーバージョンが存在するかもしれません:
脆弱性レポートによると、[email protected] にはセキュリティ問題があり、これが 1.0.1 で修正されていますが、[email protected] は影響を受けていません。foo に対して単純にオーバーライドを追加することはできません:
- 「
foo:^1.0.1」のようにオーバーライドを追加すると、[email protected]が1.0.1にダウングレードされます。これにより、依存パッケージで使用される新機能が[email protected]に含まれている場合、プロジェクトが破損する可能性があります。 - 「
foo:^2.0.0」のようにオーバーライドを追加すると、[email protected]が2.0.0にアップグレードされます。これにより、[email protected]に破損する変更がある場合、プロジェクトが破損する可能性があります。
foo がセマンティック バージョニングに従っていると仮定して、このようにオーバーライドを追加できます:
これにより、[email protected] が 1.0.1 にだけアップグレードされ、[email protected] は変更されません。
結論
PNPM が推移的依存関係を直接アップグレードする機能をサポートするまで、overrides フィールドは、問題を引き起こさずにセキュリティ脆弱性を修正するための良い対策となります。この記事がこれらのケースをより効率的に処理するのに役立つことを願っています。Logto では、この方法を使用して依存関係を最新かつ安全に保っています。

