Skip to content
Latchkey

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 ciyarn --frozen-lockfilepip install --require-hashescargo build --locked)。これはCIがlockfileの指定どおりに正確にbuildすることを保証し、静かに回避的に解決する代わりに、あらゆるdriftを知らせる。

重要なポイント

  • lockfileは、依存関係ツリー全体の正確なバージョンとhashを固定する。
  • マニフェストは意図(範囲); lockfileは実現された結果だ。
  • 再現性、安定性、セキュリティ、cache可能性のためにcommitする。
  • CIではfrozen-installモードを使い、driftを騒がしく失敗させる。

関連ガイド