Lockfileとは?
lockfileはすべての依存関係 - 直接的および推移的 - の正確なバージョンを記録し、同じinstallが毎回同じツリーを生成するようにします。
package.jsonのようなmanifestは「react ^18」と書きます。その範囲は日によって異なるバージョンに解決される可能性があります。lockfile(package-lock.json、yarn.lock、poetry.lock、Cargo.lock)は解決を凍結し、installを決定論的にします。
Manifestとlockfileの違い
manifestは、しばしばバージョン範囲として、あなたが望むものを宣言します。lockfileは、正確なバージョンとチェックサムまで、あなたが実際に得たものを記録します。lockfileは「昨日buildできた」を今日も確実にbuildできるようにするものです。
なぜCIはそれを使わなければならないのか
CIでは、lockfileからfrozenモードでinstallします - npm ci、yarn install --frozen-lockfile、poetry install。これは何かを黙ってアップグレードすることを拒否し、lockfileとmanifestが食い違う場合は大声で失敗し、driftを隠す代わりに捕捉します。
小さな例
CIでnpm installを実行すると、新しいパッチリリースを黙って解決してlockfileを変更する可能性があり、2つの実行が異なる結果になります。代わりにnpm ciを実行すると、node_modulesを削除し、package-lock.jsonから厳密にinstallし、lockfileが同期していなければ失敗します。
Lockfileはcache keyを支える
lockfileは依存関係が変わるときに正確に変わるため、そのハッシュは理想的なcache keyです。代わりにmanifestのハッシュを取ると、推移的な更新を見逃し、古いcacheを提供してしまいます。
commitしてレビューする
lockfileはバージョン管理に属します。pull requestでlockfileのdiffをレビューすると、予期しない依存関係の変更が明らかになります - 悪意ある推移的なbumpはlockfileの変更として現れるため、supply-chain防御における重要なシグナルです。
重要なポイント
- lockfileは再現可能なinstallのため、すべての依存関係の正確なバージョンを固定します。
- CIはlockfileからfrozenモードでinstallすべきで、決してそれを更新すべきではありません。
- lockfileのハッシュは依存関係にとって自然なcache keyです。