package.jsonのdependencies/devDependenciesにおいて、左端が0ではない、z.y.zという3桁のバージョンを指定する場合、以下のとおり。
記法 | 種別 | 意味 | 問題点など |
---|---|---|---|
^x.y.z | キャレット表記 | セマンティックバージョニングに従う。つまり、メジャーバージョンxを指定し、マイナーバージョンyの上昇、パッチバージョンzの上昇は互換性があるはずだと信じて、「x.{y以上}.{yが同じならz以上、yが上昇していれば任意} 」にあてはまる最新のものを使う。 | 開発時点と、ソース共有を経ての再ビルド(npm install)時の間で、NPMリポジトリ上の対象パッケージのバージョンが上がっている場合、より新しいものが使われることになる可能性があるが、セマンティックバージョニングの仕様に厳密に従わないパッケージは世の中に結構あるのではまり易い。 |
~x.y.z | チルダ表記 | セマンティックバージョニングにおける「マイナーバージョンが上がっても互換性が保たれるはずだ」という建前を信じないが、パッチバージョン上昇だったら互換性があるだろうとは信じて、「x.y.{z以上}」にあてはまるものを使う。 | キャレット表記に比べて、上記の可能性がパッチバージョンのみなので少ない。とはいえ、はまるときははまるだろう。 |
x.y.z | 固定 | 指定したバージョン「x.y.z」に厳密にあてはまるものを使う。 | 開発時と異なるバージョンが使用される問題は回避できるが、たとえばセキュリテイ問題があってそのバージョンのNPMがリポジトリから削除された場合に(互換性のある後継バージョンがあるのに)ビルド不可能になったり、許容できるバージョン上昇を指定できないなど、セマンティックバージョンのメリットを全く享受できない。 |
いずれも問題があるので、^なり~で指定した上で、package-lock.jsonなりyarn.lockを併用するのが正しい(それぞれNPM5、yarnのデフォルト動作)。
これらのロックファイルを使うのは、セマンティックバージョニングの建前と本音を使いわけることである。つまり、^~をつかって「このバージョンの範囲なら、互換性に問題ないはずだ」という希望と理想をpackage.jsonに記す。それはその上で、「実際にはこのバージョン使ってビルドしましたよ、動作保証するのはこっちなんで、こちらをお使い下さいね、げっひっひ」とlockファイルを裏で提供する。
左端の桁が0であったり、3桁以外の場合を含めてはこちらの記事などを参照のこと。