HERSHY'SのAdvent Calendar(本物)の5日目を開けたところ。
NPMおれおれAdvent Calendar 2019 – 05日目

(追記:なんか間違ってる気がするので調査中。)

言うほど秘密ってもんでもないですが。

なにそれ

package-lock.json は npm install なんかをすると生成されるファイルで、インストールされているパッケージのツリーを表します。このファイルと npm ci を利用して全く同じツリーを再構築することが可能になります。

困ったちゃん

このファイル自体は便利なものだと思うんですが、困った点がひとつ。「ロック」とう名前に反して何もロックしない点です。

ロックファイルがある状態で npm install すると、そのロックされたバージョンのパッケージ群がインストールされる、というのを期待するんですが、実際はそんなことなく、新しいものがあればそちらをインストールし、逆にロックファイルを更新します。ロックとは。

昔はロックしていた

大昔はこの package-lock.json はなく、package.json だけでした。でも package.json だとバージョンに幅を持たせた指定ができて、それはそれで便利だけどバージョンをロックもしたいよねってんでロックファイルを導入されます。

すると package.json の更新をしても実際のパッケージが更新されなくて困った、という問題があったようです。そりゃあロックしてるからな。

どうすんの

npm install の代わりに npm ci を利用してください。こちらであればロックファイルに記載のバージョンを利用してインストールが行われます。

ただし互換機能ではないので、違いには気を付けてください。こちらをどうぞ。

FAQ

package-lock.json ってなに

node_modules がどうなってるかっていう記録です。

package.json と何が違うの?

package.json はプロジェクトにまつわる諸々を載せるもので、よく自分で編集します。依存パッケージのバージョンも記載されますが、例えば "^1.0.0" のように幅のあるバージョンを指定することができます。

package-lock.json は npm が自動出力するもので、パッケージの依存関係がツリー状に保存されます。バージョンは node_modules に実際に置かれているものが記載されます。

Git リポジトリーで管理すべき?

はい。

CI で利用できるし、何か問題があったときに巻き戻すのにも使えます。

なんか git clone からの npm install で変更されちゃったんですけど?

そういうもんです。以下の選択肢があります。

  • 変更を戻してから、代わりに npm ci を利用して、プロジェクトとして現在採用されているバージョンのパッケージ群をインストールする
  • 変更を戻さずに、そのままコミットして利用バージョンを更新する

なんで npm install でロックファイルが変わるの?

package.json におけるパッケージのバージョンに幅がある場合、インストール時点で指定範囲に収まるうち最新のものがインストールされます。そのため過去の実行時よりも新しいバージョンが出ているならそちらがインストールされ、またそれに合わせてこのロックファイルが更新されてしまいます。

まあロックっていう名前が良くないよね。

編集していい?

だめ

Git でコンフリクトした

package-lock.json を削除して npm install すればちゃんとした状態でまるっと復活します。

package.json 無事でないならさきにそっちを解消してから、同じ手順です。

まとめ

  • npm install は node_modules から package-lock.json を生成する
  • npm ci は package-lock.json から node_modules を構築する

おしまい

なんか違ってたらごめん。

参考

履歴

  • 2019-12-08
    • npm ci に関する記述をもっと追加
  • 2019-12-05
    • 公開