lockfileとは何か、なぜcommitすべきか?
lockfileは、直接および推移的なすべての依存関係の、解決済みの正確なバージョン(とhash)を記録する。commitすれば、CIを含む全員が同一の依存関係ツリーに対してbuildする。
package.jsonのようなマニフェストファイルはバージョンの*範囲*を宣言する; lockfileはそれらの範囲が解決された正確なバージョンを記録する。その区別が、再現可能なbuildと「壊れたが何も変えていない」の違いだ。
マニフェスト vs lockfile
マニフェストは「lodash ^4.17.0が欲しい」と言う - 範囲だ。lockfileは「lodashは正確に4.17.21に解決された、このintegrity hash付きで」と言い - すべての推移的依存関係に同じことをする。マニフェストは意図を捉え; lockfileは実現された正確なツリーを捉える。
なぜcommitするか
- 再現性: すべてのマシンが同一のバージョンをインストールする。
- 安定性: 推移的depの新しいpatch releaseが、静かにCIを壊せない。
- セキュリティ: integrity hashが、パッケージが改ざんされていないことをインストーラに検証させる。
- cache可能性: 安定したlockfileは、自然で信頼できるcache keyだ。
lockfileがないとどうなるか
lockfileがgitignoreされているか欠けていると、各インストールが最新の一致するバージョンに対して範囲を再解決する。数日離れた2つの実行は異なる推移的依存関係を得ることがあり、コード変更なしで古典的な「自分のマシンでは通るがCIで落ちる」を生む。安定したkeyがないため、cacheも劣化する。
CIで正しく使う
lockfileから厳密にインストールし、driftで失敗するfrozen/clean-installモードを使う(npm ci、yarn --frozen-lockfile、pip install --require-hashes、cargo build --locked)。これはCIがlockfileの指定どおりに正確にbuildすることを保証し、静かに回避的に解決する代わりに、あらゆるdriftを知らせる。
重要なポイント
- lockfileは、依存関係ツリー全体の正確なバージョンとhashを固定する。
- マニフェストは意図(範囲); lockfileは実現された結果だ。
- 再現性、安定性、セキュリティ、cache可能性のためにcommitする。
- CIではfrozen-installモードを使い、driftを騒がしく失敗させる。
関連ガイド
Dependency Caching Strategies for Faster CIRe-downloading dependencies every run is wasted time. Learn what to cache, how to key it on a lockfile, and t…
Cache Key vs Restore Key: How CI Cache Lookups WorkA cache key is the exact entry to save and look up; restore keys are prefix fallbacks for a near-miss. Learn…
Retries and Idempotency in CI: Retry Safely Without Side EffectsRetrying a failed step only helps if the step is idempotent - safe to run twice. Learn what idempotency means…