package.jsonにおけるセマンティックバージョンの指定方法について - iimon TECH BLOG

iimon TECH BLOG

iimonエンジニアが得られた経験や知識を共有して世の中をイイモンにしていくためのブログです

package.jsonにおけるセマンティックバージョンの指定方法について

■はじめに

こんにちは。

株式会社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

npm: 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でプロジェクト内にインストールしているパッケージの現在バージョンと最新バージョンの差を確認できるので、

チーム内でバージョンアップを検討する際には、利用してみていいかなと思います。

■関連資料

セマンティック バージョニング 2.0.0

package.json | npm Docs

■まとめ

ソフトウェアは日々改善されているので、それに合わせてプロジェクト内で使っているパッケージのバージョンも上げることを検討する必要があると思います。

その際に、セマンティックバージョンについて知っていることは大事かなと思っています。

この記事が何かのお役に立てれば幸いです。

また、弊社ではエンジニアを募集しております。

ぜひカジュアル面談でお話ししましょう!

ご興味ありましたら、ご応募ください!

Wantedly / Green