- ■はじめに
- ■セマンティックバージョンとは何か?
- ■セマンティックバージョンの基礎知識
- ■なぜセマンティックバージョンを使うのか?
- ■環境構築
- ■パッケージ情報を調べてみる
- ■バージョン指定方法を試してみる
- ■アップデートが必要なパッケージを調べる
- ■関連資料
- ■まとめ
■はじめに
こんにちは。
株式会社iimonでフロントエンドを担当している白水です。
今回は、package.json
ファイルでよく見る「セマンティックバージョン」の指定方法について書いていきます。
■セマンティックバージョンとは何か?
「セマンティックバージョン」とは、「X.Y.Z(Major.Minor.Patch)」というバージョンフォーマットで、パッケージのバージョンを表す方法です。
■セマンティックバージョンの基礎知識
◆パッチバージョン:patch
「"typescript": "^5.6.2"」の「2」の部分をパッチバージョンといいます。
後方互換性のあるバグ修正など、軽微な変更があった際は「パッチバージョン」がバージョンアップします。
◆マイナーバージョン:minor
「"typescript": "^5.6.2"」の「6」の部分をマイナーバージョンといいます。
後方互換性のある、新しい機能を導入されたときに「マイナーバージョン」がアップデートされます。
◆メジャーバージョン:major
「"typescript": "^5.6.2"」の「5」の部分をメジャーバージョンといいます。
メジャーバージョンが上がった場合は、後方バージョンと互換性がない場合があるので、パッケージの動作やパッケージの使い方を更新しなければいけません。
■なぜセマンティックバージョンを使うのか?
上で示したバージョン指定方式を "セマンティック・バージョン"と呼んでいます。
"セマンティック・バージョン"でバージョンを表すことで、バージョン変更があった際に、どの程度の規模で変更されたのかというの意味を伝えることができます。
■環境構築
いろんな"セマンティック・バージョン"指定方法を試すために環境を作ります。
❯ mkdir sample ❯ cd sample/ ❯ npm init -y
好きな場所にディレクトリを作って、package.json
ファイルを作成します。
❯ npm i semver
セマンティックバージョンの確認のため、semver
というライブラリをインストールしておきます
■パッケージ情報を調べてみる
❯ npm view uuid
npm view <パッケージ名>
と打つと、そのパッケージの情報を調べることができます。
latest: 10.0.0
なので、最新の安定版は「5.6.2」です。
❯ npm view uuid versions
今までリリースされたバージョンの一覧を確認した場合は、npm view <パッケージ名> versions
と打てば確認できます。
■バージョン指定方法を試してみる
◆バージョンの直接指定
❯ npm install uuid@7.0.0 --save-exact
uuid@7.0.0
をバージョン固定でインストールしてみます。
--save-exact
オプションを使用することで、package.json
に記載されるバージョンを "uuid": "7.0.0"
のように厳密な形式で保存できます。
--save-exact
を使わない場合、npmのデフォルトの挙動に従って、^
や ~
がバージョン番号の前に付きます。
package.jsonを確認すると、"uuid": "7.0.0”
と指定されています。
package-lock.jsonの"node_modules/uuid”のバージョンも"version": "7.0.0”になっています。
◆指定バージョンより大きい中で最新の安定版
❯ touch main.js
semver
で検証するため、JSファイルを作成してみます。
const semver = require('semver'); const rangeInstance = new semver.Range('>8.3.0'); console.log(rangeInstance.range);
new semver.Range()
の引数にバージョンを指定すると、どの範囲のバージョンを許容するのか確認できます。
❯ node main.js >8.3.0
node main.js
で実行してみると、「>8.3.1」と表示されるので、「8.3.1」より大きい最新の安定版がインストールされることがわかります。
// package.json "dependencies": { "uuid": ">8.3.0" }
package-lock.json
ファイルとnode_modules
を削除して、package.jsonに"uuid": ">8.3.0"
を記載してみます。
(コマンドで">8.3.0"
と指定する方法が不明でした)
その後、npm install
コマンドを実行してみます。
package-lock.jsonの"node_modules/uuid”のバージョンを確認してみると、"10.0.0”になっています。
これは">8.3.0"
という記載が、"8.3.0"
より大きい最新の安定版をインストールすることになるので、npm view uuid
で確認した
latest: 10.0.0
がインストールされています。
◆指定バージョン以上で最新の安定版
const semver = require('semver'); const rangeInstance = new semver.Range('>=8.3.0'); console.log(rangeInstance.range); // >=8.3.0
>=8.3.0
という記載が、指定バージョン以上で最新の安定版を指定する方法です。
ほとんど、>8.3.0
と同じですが、「8.3.0」を含めるかどうかの違いがあります。
// package.json "dependencies": { "uuid": ">=8.3.0" }
package-lock.json
ファイルとnode_modules
を削除して、package.jsonに"uuid": ">=8.3.0"
を記載してみます。
その後、npm install
コマンドを実行してみます。
">=8.3.0"と指定したときと同じように、latest: 10.0.0がインストールされています。
◆指定バージョン未満で最新の安定版
const semver = require('semver'); const rangeInstance = new semver.Range('<8.3.0'); console.log(rangeInstance.range); // <8.3.0
<8.3.0
という記載が、指定バージョン未満で最新の安定版を指定する方法です。
// package.json "dependencies": { "uuid": "<8.3.0" }
package-lock.json
ファイルを削除して、package.jsonに"uuid": "<8.3.0"
を記載してみます。
その後、npm install
コマンドを実行してみます。
そうすると、"version": "8.2.0"がインストールされます。
npm view uuid versions
コマンドでバージョン一覧を確認してみると、「8.3.0」未満で最新の安定版は「8.2.0」なので、「8.2.0」がインストールされます。
◆指定バージョン以下で最新の安定版
const semver = require('semver'); const rangeInstance = new semver.Range('<=8.3.0'); console.log(rangeInstance.range);
<=8.3.0
という記載が、指定バージョン以下で最新の安定版を指定する方法です。
// package.json "dependencies": { "uuid": "<=8.3.0" }
package-lock.json
ファイルとnode_modules
を削除して、package.jsonに"uuid": "<=8.3.0"
を記載してみます。
その後、npm install
コマンドを実行してみます。
「8.3.0」以下で指定しているので、「8.3.0」以下で最新の安定版である、「8.3.0」がインストールされています。
◆チルダ「~」を使ったバージョン指定
const semver = require('semver'); const rangeInstance = new semver.Range('~3.2.0'); console.log(rangeInstance.range);
「~3.2.0」と記載して、バージョンの範囲を確認してみます。
❯ node main.js >=3.2.0 <3.3.0-0
実行してみると、「3.2.0以上」〜「3.3.0未満」の範囲になることがわかります。
なので、バージョン3.2.0と同じマイナーバージョンの中で、パッチバージョンが最新のバージョンを利用することができます。
// package.json "dependencies": { "uuid": "~3.2.0" }
package-lock.json
ファイルとnode_modules
を削除して、package.jsonに"uuid": "~3.2.0"
を記載してみます。
その後、npm install
コマンドを実行してみます。
「3.2.1」がインストールされています。
「~」での指定の場合、バグ修正(パッチバージョンアップ)は取り込むけど、「メジャーバージョンアップ」や「マイナーバージョンアップ」は取り込まないという場合に利用することが多いです。
◆キャレット指定
const semver = require('semver'); const rangeInstance = new semver.Range('^3.0.0'); console.log(rangeInstance.range);
「3.0.0」と記載して、バージョンの範囲を確認してみます。
❯ node main.js >=3.0.0 <4.0.0-0
実行してみると、「3.0.0」以上〜「4.0.0」未満の範囲になることがわかります。
なので、後方互換性のあるバージョンアップ(マイナーバージョンとパッチバージョン)は受け入れるようになります。
// package.json "dependencies": { "uuid": "^3.0.0" }
package-lock.json
ファイルとnode_modules
を削除して、package.jsonに"uuid": "~3.2.0"
を記載してみます。
その後、npm install
コマンドを実行してみます。
3系の中で、マイナーバージョンが最新の安定版は「3.4.0」なので、「3.4.0」がインストールされています。
キャレットで指定するのが、1番オーソドックスかなと思います。
◆その他(詳細は省略)
- パッチバージョンとマイナーバージョンの省略(ex. ~1.2、~1、^ 1.2、^ 1)
- エックス指定:1.2.x/1.2.X
- アスタリスク指定:*
- ハイフン指定:1.2.3 – 2.0.0
- 「latest」を指定
その他にも、上のようなバージョン指定方法もあります。
興味のある方は調べてみてください。
■アップデートが必要なパッケージを調べる
❯ npm outdated
セマンティックバージョンの指定方法について知るのは、パッケージをインストールする場合と、バージョンアップする際に必要かなと感じています。
パッケージのバージョンを上げる際に、どんな記載でどこまでバージョンが上がるのか知っていると、上げやすいのかなと思います。
npm outdated
でプロジェクト内にインストールしているパッケージの現在バージョンと最新バージョンの差を確認できるので、
チーム内でバージョンアップを検討する際には、利用してみていいかなと思います。
■関連資料
■まとめ
ソフトウェアは日々改善されているので、それに合わせてプロジェクト内で使っているパッケージのバージョンも上げることを検討する必要があると思います。
その際に、セマンティックバージョンについて知っていることは大事かなと思っています。
この記事が何かのお役に立てれば幸いです。
また、弊社ではエンジニアを募集しております。
ぜひカジュアル面談でお話ししましょう!
ご興味ありましたら、ご応募ください!