【npm,yarn】今さら聞けないlockファイル
はじめに
今回はyarn.lock
やpackage-lock.json
等のlock
ファイルに関する内容です。
この辺りは検索をすれば同様の記事がヒットしますが、自信の備忘として改めて記事に起こしています。
package.jsonのバージョン表記方法について
lock
ファイルの役割を知るにはまず、package.json
にライブラリをインストールした際の登録されるバージョンの表記方法について理解しておく必要があります。
例えば、hogehoge
というライブラリを以下のコマンドでインストールしたとします。
yarn add hogehoge
するとpackage.json
のdependencies
は下記のようになりました。
{
"hogehoge": "^1.2.1"
}
1.2.1
というバージョンの先頭にキャレット^
が付いています。
このようにyarn
やnpm
でライブラリをインストールした場合にpackage.json
に書き込まれるバージョンにはいくつか種類があります。
その内容をまとめたのが下記表になります。
表記 | 意味 |
---|---|
1.2.1 |
1.2.1 で固定 |
>=1.2.1 |
1.2.1 以降のバージョン(<,> などの不等号で指定) |
1.2.x | xはなんでもOK |
^1.2.1 |
1.2.1 以降で、メジャーバージョンが変わらない |
大概のライブラリがキャレット付きのパターンを使用しているかと思います。
ライブラリもまたライブラリに依存している
この時点で、node_modules
の中にhogehoge
ライブラリが入っていますが、その中にもさらにpackage.json
があるかと思います。
そしてその中のdependencies
に以下の記載があったとします。
{
"fugafuga": "^3.0.1"
}
これはhogehoge
ライブラリがfugafuga
ライブラリに依存していることを意味します。
パッケージマネージャーの機能として、参照先のライブラリもよしなにインストールしてくれるので、基本的にはhogehoge
がインストールされたタイミングでfugafuga
もnode_modules
に入っていると思います。
※ルートのpackage.json
にfugafuga
は記載されないため注意
異なるバージョンのライブラリをインストールする
さらに別なライブラリであるpunipuni
をインストールしてみました。
するとルートのpackage.json
のdependencies
は以下のようになりました。
{
"hogehoge": "^1.2.1",
"punipuni": "^4.3.0"
}
そしてnode_modules/punipuni
のpackage.json
には下記のような記述がありました。
{
"fugafuga": "^3.2.1"
}
punipuni
もfugafuga
に依存していますが、そのバージョンが異なります。
世に公開されているfugafuga
の最新バージョンは3.3.1
なので、ここでは^3.0.1
と^3.2.1
の両方を満たす3.3.1
がインストールされました。
lock
がない場合の問題点
ここまでの作業をAさんが行ったとします。
少し時間を置いてAさんと同様の環境を構築しようとしたBさんが、AさんがGit
で共有したpackge.json
を取得してyarn install
を行いました。
この時hogehoge
やfugafuga
そしてpunipuni
にさらに新しいバージョンが公開されていた場合、Bさんのローカルに構築した環境はAさんとは同じになりません。
なぜなら
{
"hogehoge": "^1.2.1",
"punipuni": "^4.3.0"
}
のように「X.X.X
以降で、メジャーバージョンが変わらないバージョン」のような指定をしているため、より新しいバージョンが存在する場合、そちらがインストールされてしまうからです。
この問題を防いでいるのがlock
ファイルです。
yarn.lock
はこうなっている
試しにyarn.lock
ファイルの中を見てみましょう。
Aさんがhogehoge
とpunipuni
を入れ終わった段階でyarn.lock
は以下のようになっています。
hogehoge@^1.2.1:
version "1.3.1"
resolved "https://......."
integrity sha512-hogehogehoge
dependencies:
fugafuga "^3.0.1"
punipuni@^4.3.0:
version "4.4.1"
resolved "https://......."
integrity sha512-punipunipuni
dependencies:
fugafuga "^3.2.1"
fugafuga@^3.0.1, fugafuga@^3.2.1:
version "3.3.1"
resolved "https://......."
integrity sha512-fugafugafuga
lock
ファイルは 「依存関係まで含めて、実際にどのバージョンがインストールされているか」 を管理します。
それぞれのライブラリのversion
の項目がそれにあたります。
パッケージマネージャーは基本的に、lock
ファイルがあればそちらの記載に従うので、lock
ファイルを共有することで 「誰がインストールしても同じバージョンがインストールされる」 ことを担保することができます。
npm install
とyarn add
の両方を使っていると、どちらか片方を使った方がよいといった旨の警告が出ます。
なぜかというとnpm
はpackage-lock.json
を、yarn
はyarn.lock
を参照するため、人によっては異なったバージョンがインストールされる可能性があるからです。
まとめ
今回はlock
ファイルについて、どんな役割を持っているかを紹介しました。
自分はJS
開発を始めたての頃に、 「package.json
さえあればどのバージョンが入っているかは分かるから、このよくわからないlock
ファイルはGit
で管理しなくてもいいのでは?」 と思ってignore
してしまったことがありますが、今となっては恐ろしい話です。
一見するとそれでも問題なく動作しているように見えますが、複数人で開発している場合は厳密にライブラリのバージョンを合わせた方が、バージョンの際による挙動の違いが発生しなくなるので安全です(当然ですが・・・)。
この記事が少しでも役立ちましたら幸いです。
Discussion