LoginSignup
12
8

More than 1 year has passed since last update.

package.jsonとpackage-lock.jsonのバージョン指定や必要性について

Last updated at Posted at 2021-10-09

はじめに

業務内でpackage.jsonやpackage-lock.jsonを使う機会があり、学んだことをまとめる。

Node.jsとnpm

メインの話ではないので細かい説明は省略。

・Node.js
Node.jsは、「JavaScriptの実行環境」。Node.jsを使うことで、サーバー側でJavaScriptを使うことが出来るようになる。

・npm
npmは、Node Package Manuagerの略でNode.jsのパッケージ管理ツール。

詳しい説明はこちらを→Node.jsとはなにか?なぜみんな使っているのか?

npmはNode.jsをインストールする際に一緒にインストールされる。

package.jsonとpackage-lock.jsonについて

Semantic Version

Semantic Versionとは、バージョン番号を付けるにあたり決めたルールのこと。

細かい仕様については、下記サイトでまとまっている。
セマンティック バージョニング 2.0.0

Node.jsでは、このSemantic Versioning(semver)に従ってバージョン表記をしている。
semverでは、以下のようにX.Y.Zのように3つの数字で表される。

  • X:major version 後方互換性のない変更
  • Y:minor version 後方互換性のある変更
  • Z:patch version 後方互換性のあるバグ修正など

メジャーバージョンが上がると、マイナーバージョンとパッチバージョンの値は0となる。
マイナーバージョンが上がると、パッチバージョンの値は0となる。

メジャーバージョンは後方互換性がない変更であるため、その点注意する必要がある。

例)

"devDependencies": {
        "bootstrap": "^4.0.0"
}

この例の場合は、bootstrapパッケージでメジャーバージョンが4、マイナーバージョンと、パッチバージョンが0という風に対応している。

ただ、注意する点として先頭についている^(キャレット)がある場合は、あるルールにのっとってその範囲内のバージョンへのアップデートを許容する。

^(キャレット)

上記の例でもあったようにバージョン指定する際に、"bootstrap": "^4.0.0"のように記載してあることがある。この先頭についているものが^(キャレット)である。

キャレットについて、npm Docsに以下のような説明があります。

Caret Ranges ^1.2.3 ^0.2.5 ^0.0.4
Allows changes that do not modify the left-most non-zero digit in the [major, minor, patch] tuple.
引用元:semver

翻訳すると、

[major, minor, patch]タプルの左端のゼロ以外の数字を変更しない変更を許可します 。

どういうことか実際にいくつかの例をもとに説明する。

^1.2.3の場合
一番左端のゼロ以外の数字はメジャーバージョンを示す1。そのため、メジャーバージョンを変更しないようなアップデートを許容する。
ここでのバージョンアップ許容範囲は、 1.2.3 <= N < 2.0.0となる。

0.2.3の場合
一番左端のゼロ以外の数字はマイナーバージョンを示す2。そのためメジャーバージョンとマイナーバージョンを変更しないようなアップデートを許容する。
ここでのバージョンアップ許容範囲は、0.2.3 <= N < 0.3.0となる。

0.0.3の場合
一番左端のゼロ以外の数字はパッチバージョンを示す3。そのため、ここでのバージョンアップ許容範囲は、0.0.3 <= N < 0.0.4となる。

~(チルダ)

キャレットの他にもバージョン範囲指定がいくつかありその中に~(チルダ)がある。

npm Docsに以下のような説明があります。

Tilde Ranges ~1.2.3 ~1.2 ~1
Allows patch-level changes if a minor version is specified on the comparator. Allows minor-level changes if not.

翻訳すると、

コンパレータでマイナーバージョンが指定されている場合、パッチレベルの変更を許可します。そうでない場合は、マイナーレベルの変更を許可します。

どういうことか実際にいくつかの例をもとに説明する。

~1.2.3の場合
この場合は、マイナーバージョン部分の2が指定されているため、パッチレベルのアップデートを許容する。バージョンアップ許容範囲は、1.2.3 <= N < 1.3.0となる。

~1.2の場合
この場合は、マイナーバージョン部分の2が指定されているため、パッチレベルのアップデートを許容する。バージョンアップ許容範囲は、1.2.3 <= N < 1.3.0となる。

~1の場合
この場合は、マイナーバージョンが指定されていないため、マイナーバージョンのアップデートを許容する。バージョンアップ許容範囲は、1.0.0 <= N < 2.0.0となる。

参考

package-lock.jsonの必要性

今回学習初期段階のイメージとしては、package.jsonに記述してあるバージョンを入れて、入れたバージョン情報などがpackage-lock.jsonに自動的に記述されるだけという感じだった(不十分)。

しかし、先ほどのSemantic Versionでも触れたようにpackage.jsonでは入れるバージョンをある程度の範囲で指定することができる。そのため、実際にパッケージをインストールするタイミングによってはパッケージのバージョンが異なってしまうという問題がある。

チーム内で同じ環境を構築したい場合、バージョンが異なってしまうと困る。
このインストールするバージョンを固定するために必要なのが、package-lock.jsonである。

npm installを実行する際、package-lock.jsonがない場合はpackage.jsonに従ってパッケージがインストールされますが、package-lock.jsonがある場合は基本的にはpackage-lock.jsonのバージョンで固定してインストールすることが出来る

これを自分は知らなかったため、最初インストールしたバージョンが他の環境と異なってしまうという問題に遭遇した。

これらのことから、どちらのファイルも非常に重要であるためもしGit管理する場合はどちらもコミットする必要がある。

また、npm installの具体的な挙動として以下のようになっているとのこと。

npm v6.9.0 時点ではnpm installの具体的な挙動は次のようになっている。
package-lock.jsonが存在しないとき
package.jsonに基づいて dependency がインストールされ、実際にインストールされたバージョンがpackage-lock.jsonに書かれる。
package-lock.jsonが存在するとき
package-lock.jsonに基づいてインストールされるが、package.json指定されたバージョンとの矛盾があれば、package.jsonが優先され、実際にインストールされたバージョンがpackage-lock.jsonに書かれる。
引用元:【初心者向け】NPMとpackage.jsonを概念的に理解する

package.jsonとpackage-lock.jsonの指定バージョンに矛盾があった場合は、package.jsonが優先されるとのことなのでこの点注意したい。

参考

package.jsonとpackage-lock.jsonの運用方法について

まとめ

今回は、package.jsonとpackage-lock.jsonのバージョン指定や必要性について簡単にまとめた。
まだまだ、理解が不十分であるため引き続き理解を深めていきたいと思います。

12
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
12
8