コンテンツへスキップ
LatchkeyLatchkey home

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を騒がしく失敗させる。

よくある質問

What is What is a lockfile and why should you commit It??
Manifest files like package.json declare version *ranges*; a lockfile records the exact versions those ranges resolved to. That distinction is the difference between a reproducible build and "it broke and nothing changed".
Manifest vs lockfile?
A manifest says "I want lodash ^4.17.0" - a range. A lockfile says "lodash resolved to exactly 4.17.21, with this integrity hash" - and does the same for every transitive dependency. The manifest captures intent; the lockfile captures the exact realized tree.
What happens without one?
If the lockfile is gitignored or missing, each install re-resolves the ranges against the latest matching versions. Two runs days apart can get different transitive dependencies, producing the classic "passes on my machine, fails in CI" with no code change. Caching also degrades because there is no stable key.
Using it correctly in CI?
Use the frozen/clean-install mode that installs strictly from the lockfile and fails on drift (npm ci, yarn --frozen-lockfile, pip install --require-hashes, cargo build --locked). That guarantees CI builds exactly what the lockfile specifies and flags any drift instead of silently resolving around it.

関連ガイド