【package.json】 バージョンにつける「^」「~」は何を意味するのか?
Share this post
はじめに
Another works でエンジニアをしているまっちです!
今回は**【package.json】 バージョンにつける「^」「~」は何を意味するのか?**というテーマを深掘って書いていきます!
自分の感覚では^
チルダはじまりでpackage.json
にのバージョン指定がされているライブラリが多い印象です。
そこで ^
や `~' ってなんでつけてるの?
という疑問から色々と調べたことを書いていきます。
"dependencies": {
"react": "^18.2.0", // これ
"next": "~12.0.2", // これ
,,,
^ 表記で破壊的な変更がない範囲で最新バージョンを利用できる
package.json
に^
表記でバージョン指定が多い理由として
package
を破壊的な変更がない範囲で最新の機能を利用できるバージョンにできる(はず)だから、
と考えました。(違ったらすみません!)
その理由を後述していきます。
前提として、
package.json
の仕様npm
の推奨しているセマンティックバージョニングについて
理解したあと、
package.json
のバージョン指定方法を説明しながら考えてみます。
前提1: package.json にはバージョン範囲を記述する
package.jsonには
インストールする package の範囲を記述します。
package.lock.jsonには
実際にインストールされている package のバージョン(などの)情報が記載されます。
つまり、node_modules
に入っている package 郡の情報が記載されます。
前提2: npm の推奨しているセマンティックバージョニング
ざっくり、npm
はパッケージを
意味のある数字でバージョンを管理しようぜ、ということを推奨しています。
※セマンティック(semantic): 意味の, 語義の, 意味論的な
https://docs.npmjs.com/about-semantic-versioning
このセマンティックバージョニングではバージョンを表す3つの数字x.x.x
に
[major, minor, patch]
という意味をもたせています。
それぞれの意味するところは次のようなものです。
major
:前のバージョンと互換性を損なう変更
をするときに上げる数字minor
:前のバージョンと互換性を持つ新機能追加の変更
をするときに上げる数字patch
:前のバージョンと互換性を持つバグ修正の変更
をするときに上げる数字
※つまりmajorアップデート
では破壊的な変更を含む可能性が高いということです。
例を用いて考える
3.4.5
というバージョンが最新のpackage
があった場合、
セマンティックバージョニングに則れば
majorアップデート
を3回- 3系になって(
majorアップデート
3回目以降)からminorアップデート
を4回patchアップデート
を5回
おこなっているpackageということになります。
package.json のバージョン指定方法
~
, ^
を含めて大きく4つのバージョン指定方法があるようです。
https://www.npmjs.com/package/semver/v/4.3.6
1. バージョンの数字のみ記載
範囲なし(固定)
記載したバージョンをインストールする。
1.2.3
: 1.2.3 (記述したバージョンのみ許容)
2. x
or *
x
, *
を記載した箇所のバージョン更新を許容
*
: >=0.0.0 (どのバージョンの更新も許容)1.x
: >=1.0.0 <2.0.0 (major バージョン以外の更新を許容)1.2.x
: >=1.2.0 <1.3.0 (patch バージョンだけの更新を許容)
3. ~
チルダ
minorバージョンが指定されている場合、patchバージョンの変更を許容。そうでない場合は、minorバージョンの変更を許容。
~1.2.3
: 1.2.3以上 1.3.0未満~1
: 1.0.0以上 2.0.0未満
4. ^
キャレット
3つの数字[major, minor, patch]
で1番左側にある0
でない数字を変更しない更新を許可。(ややこしい)
^1.2.3
:1.2.3以上 2.0.0未満(1の変更は許容しない)^0.2.3
:0.2.3以上 0.3.0未満(2の変更は許容しない)^0.0.3
:0.0.3以上 0.0.4未満(3の変更は許容しない,つまり変更不可?)
つまりmajor
バージョンの更新を許容せずに最新バージョンに更新することを許容するようです。
なるほど、つまり
^
チルダ表記でバージョン指定をすれば前のバージョンとの互換性を保ちながら、最新バージョンに保たれる可能性が高いといえます。
ただし、セマンティックバージョニングに則っているpackageであること(majorアップデート以外で破壊的な変更がされない)という前提があります。
さいごに
恥ずかしながら今回書いたことは調べるまで知らないことだらけでした。
ライブラリ(package)の開発者も利用者もセマンティック バージョニングについて理解しながら開発をすることが大事だと感じました。
お読みくださりありがとうございました!
参考
参考にさせていただきました。ありがとうございました。
- https://zenn.dev/luvmini511/articles/56bf98f0d398a5
- https://zenn.dev/ikuraikura/articles/d6ff3821017e29539a7a
- https://www.npmjs.com/package/semver/v/4.3.6
- https://docs.npmjs.com/about-semantic-versioning
Share this post