lockファイルの恩恵を確認したい!
Nodejsのモジュールをコマンドでインストールすると、
-
npm install
の場合 =>package-lock.json
-
yarn install
の場合 =>yarn-lock.json
がどれぞれ生成される。
なんかバージョンを固定するのに役立つと聞くけど、いまいちどんな恩恵があるのかわかってなかったので、動作を確認してみる。
環境
- node : v12.13.0
- npm : 6.12.0
- yarn : 1.19.1
確認
npm
, yarn
でそれぞれlodash
をinstallして、色々変更しながら入るバージョン確認していく。
lodashは2019/10/24の時点で、4系はv4.17.15まで、3系はv3.10.1までがnpmに公開されている。
https://www.npmjs.com/package/lodash
npmでの確認
lodash v3.0.0のインストール
適当なディレクトリを作成して、npmでlodashの3.0.0指定してをインストールする。
$ npm init -y
$ npm install lodash@3.0.0 --save
node_moduleに入っているlodashのバージョンを確認すると、期待通りにlodashの3.0.0がインストールされている。
$ grep '"version":' node_modules/lodash/package.json
"version": "3.0.0"
このときのpackage.jsonとpackage-lock.json下記のようになる。
"dependencies": {
"lodash": "^3.0.0"
}
- lodashのバージョン指定は
^3.0.0
と記述されて、少しゆるい指定の「3系の最新ちょうだい(3.0.0 <= x < 4.0.0)」となる。
"dependencies": {
"lodash": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-3.0.0.tgz",
"integrity": "sha1-STNktxg6NxBNZSVfOLD+WGnL4P0="
}
}
- インストールするバージョンは
3.0.0
であると記述される("version": "3.0.0"
)
node_modulesのみを削除して再インストール
node_modules
を削除してnpm install
をすると...3.0.0がインストールされる。
$ rm -rf node_modules
$ npm install
$ grep '"version":' node_modules/lodash/package.json
"version": "3.0.0"
package-lock.jsonとnode_modulesを削除して再インストール
node_modules
と**一緒にpackage-lock.json
**を削除してnpm install
をすると...3.10.1がインストールされる。
$ rm -rf node_modules package-lock.json
$ npm install
$ grep '"version":' node_modules/lodash/package.json
"version": "3.10.1"
これはpackage.json
でのlodashのバージョン指定が「3系の一番新しいやつ」とゆるい指定になっているため。
"dependencies": {
"lodash": "^3.0.0"
}
package-lock.json
がある間はしっかりバージョン指定されるが、なくなるとpackage.json
のゆるい指定にひっぱられる。
また、このときにpackage-lock.json
はその時のlodashのバージョンにロックされたもので再生成される。
package.jsonの記述を変更する(~3.0.0
)
(一旦、lodashのバージョンを3.0.0で指定してインストールし直す)
package.json
のlodashのバージョン指定方法を^3.0.0
=> ~3.0.0
へ変更する。
"dependencies": {
"lodash": "~3.0.0"
}
この状態でnode_modules
を削除してnpm install
をすると...3.0.0
がインストールされる。
$ rm -rf node_modules
$ npm install
$ grep '"version":' node_modules/lodash/package.json
"version": "3.0.0"
~3.0.0
は 「3.0.0 <= x < 3.1.0」を取得する記述で、package-lock.json
で指定されているバージョンが3.0.0なため、
package-lock.json
に書かれているバージョンが採用される。
package.jsonの記述を変更する(^4.0.0
)
package.json
のlodashのバージョン指定方法を^3.0.0
=> ^4.0.0
へ変更する。
"dependencies": {
"lodash": "^4.0.0"
}
この状態でnode_modules
を削除してnpm install
をすると...4.17.15がインストールされる。
$ rm -rf node_modules
$ npm install
$ grep '"version":' node_modules/lodash/package.json
"version": "4.17.15"
^4.0.0
は 「4.0.0 <= x < 5.0.0」を取得する記述で、package-lock.json
で指定されているバージョンが3.0.0だけど、
package.json
の指定の範囲外なので、package-lock.json
の内容は無視されて、4系の最新の4.17.15
がインストールされる。
また、このときにpackage-lock.json
はその時のlodashのバージョンにロックされたもので再生成される。
yarnでの確認
lodash v3.0.0のインストール
適当なディレクトリを作成して、yarnでlodashの3.0.0指定してをインストールする。
$ yarn init -y
$ yarn add lodash@3.0.0
node_moduleに入っているlodashのバージョンを確認すると、期待通りにlodashの3.0.0がインストールされている。
$ grep '"version":' node_modules/lodash/package.json
"version": "3.0.0"
このときのpackage.jsonとpackage-lock.json下記のようになる。
"dependencies": {
"lodash": "3.0.0"
}
- lodashのバージョン指定は
3.0.0
と記述されて、厳密に指定した「3.0.0のバージョンがほしい」となる。
lodash@3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-3.0.0.tgz#493364b7183a37104d65255f38b0fe5869cbe0fd"
integrity sha1-STNktxg6NxBNZSVfOLD+WGnL4P0=
- package.jsonでの「lodash指定は
3.0.0
」だった。(lodash@3.0.0:
) - インストールするバージョンは
3.0.0
であると記述される(version "3.0.0"
)
node_modulesのみを削除して再インストール
node_modules
を削除してyarn install
をすると...3.0.0がインストールされる。
$ rm -rf node_modules
$ yarn install
$ grep '"version":' node_modules/lodash/package.json
"version": "3.0.0"
yarn.lockとnode_modulesを削除して再インストール
node_modules
と**一緒にpackage-lock.json
**を削除してnpm install
をすると...3.0.0がインストールされる。
$ rm -rf node_modules package-lock.json
$ yarn install
$ grep '"version":' node_modules/lodash/package.json
"version": "3.0.0"
package.json
での指定がnpmとは違って厳密なので、3.0.0がインストールされる。
また、このときにyarn.lock
がなくなっていたので、その時のlodashのバージョンにロックされたもので再生成される。(消す前と全く同じ内容)
package.jsonの記述を変更する(~3.0.0
)
package.json
のlodashのバージョン指定方法を^3.0.0
=> ~3.0.0
へ変更する。
"dependencies": {
"lodash": "~3.0.0"
}
この状態でnode_modules
を削除してyarn install
をすると...3.0.1
がインストールされる。
$ rm -rf node_modules
$ yarn install
$ grep '"version":' node_modules/lodash/package.json
"version": "3.0.1"
yarn.lock
内での記述は、
- package.jsonでの「lodash指定は
3.0.0
」だった。(lodash@3.0.0:
)
となっていたけど、package.jsonでの指定方法が~3.0.0
に変更したせいで、yarn.lock
の記述と一致しなくなったため、yarn.lock
の指定が無視されるようになる。
また、このときにyarn.lock
はその時のlodashのバージョンにロックされたもので再生成される。
package.jsonとyarn.lockの記述を同じように変更する(~3.0.0
)
(一旦、lodashのバージョンを3.0.0で指定してインストールし直す)
package.json
と yarn.lock
バージョン指定をそれぞれ~3.0.0
へ変更する
"dependencies": {
"lodash": "~3.0.0"
}
lodash@~3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-3.0.0.tgz#493364b7183a37104d65255f38b0fe5869cbe0fd"
integrity sha1-STNktxg6NxBNZSVfOLD+WGnL4P0=
この状態でnode_modules
を削除してnpm install
をすると...3.0.0がインストールされる。
$ rm -rf node_modules
$ yarn install
$ grep '"version":' node_modules/lodash/package.json
"version": "4.17.15"
package.json
の指定が変更されたが、一緒にyarn.lock
の指定も変更したため、それぞれの指定がずれなかったためyarn.lock
の指定されたバージョンがインストールされた。
まとめ
package-lock.json
と yarn.lock
でバージョンをロックしてくれた。
ただ、package.json
を変更したときの、無視する条件が異なった。
-
package-lock.json
(npm)-
package.json
の指定内容がpackage-lock.json
の指定範囲を外れてしまったら、無視される。- 逆に、指定範囲内なら記述を変えても
package-lock.json
は有効
- 逆に、指定範囲内なら記述を変えても
-
-
yarn.lock
(yarn)-
package.json
の指定内容が、yarn.lock
内での記述方法が一致しなくなったら、無視される。
-
npmからyarnに乗り換えるときとか、package.json
のバージョン指定を整理するときとかはこの仕様の違いに注意したほうが良さそう。
おまけ
調べている途中で気づいたけど、 npm install lodash@3.0.0
とyarn add lodash@3.0.0
でpackage.jsonの記述内容が変わるのが意外だった。個人的にはバージョン指定はしっかり固定したほうが安心派なので、yarnのほうが好き。
あと、
package.json
の指定内容がpackage-lock.json
の指定範囲を外れてしまったら、無視される。
この挙動はnpmのv6.12.0
あたりからの仕様っぽい。
nodeのv10とかで使われる、 npmのv6.4.1
ではこの挙動はしないで、package-lock.json
の指定は勝手にはずれなかった。
好みの問題かもしれないけど、nodeのバージョンアップ時(v10
=> v12
)になにか地雷を踏みそうで怖い。