Back

セマンティックバージョニング徹底解説

セマンティックバージョニング徹底解説

package.json ファイルを開いて、なぜある依存関係には ^1.4.2 と表示され、別のものには ~2.0.1 と表示されているのか不思議に思ったことがあるなら、あなたはすでにセマンティックバージョニングの実用的な影響に直面しています。SemVer の仕組みを理解することで、依存関係の更新についてより良い判断ができ、ビルドの破損を回避し、自分でパッケージを公開する際に変更内容を明確に伝えることができます。

重要なポイント

  • SemVer は MAJOR.MINOR.PATCH 形式を使用し、各セグメントは特定の種類の変更(破壊的、追加的、修正的)を示します。
  • npm のレンジ演算子(^~、および完全一致バージョン)は依存関係の更新方法を制御し、キャレットがデフォルトであり、メジャーバージョン内では最も寛容です。
  • package-lock.json のようなロックファイルは、指定されたレンジに関係なく、チームや CI 環境間で再現可能なインストールを保証します。
  • 1.0.0 未満のバージョンは不安定とみなされ、プリリリースタグ(例: 1.0.0-beta.1)は明示的に不安定なリリースとして扱われ、明示的に要求しない限り通常のレンジでは npm にインストールされません。
  • SemVer はメンテナーと利用者の間の社会的契約であり、技術的な強制メカニズムではありません。

セマンティックバージョニングとは何か

セマンティックバージョニング(SemVer) は、バージョン番号に意味を割り当てるバージョニング仕様です。SemVer のバージョンは MAJOR.MINOR.PATCH の形式を取り、各番号は特定の種類の変更を示します:

  • MAJOR — 以前の公開 API と互換性のない破壊的変更
  • MINOR — 後方互換性を保ちながら追加された新機能
  • PATCH — 後方互換性のあるバグ修正

パッケージが 2.6.9 から 3.0.0 に移行した場合、後方互換性が破壊されたことを意味します。2.6.9 から 2.7.0 への移行は、何も壊さずに機能を追加します。2.6.10 への移行はバグ修正です。

ひとつ重要な明確化: SemVer は、パッケージに定義された公開 API がある場合にのみ意味を持って機能します。パッケージとその利用者の間の明確な契約がなければ、バージョン番号は単なる数字にすぎません。

npm が依存関係レンジに SemVer をどう使うか

npm のバージョニングは SemVer を直接ベースにしていますが、package.json のレンジ構文はその上にある層であり、SemVer そのものではありません。

"dependencies": {
  "lodash": "^4.17.21",
  "axios": "~1.6.0",
  "react": "18.2.0"
}

それぞれのレンジ演算子の意味は以下の通りです:

  • ^(キャレット) — MINOR および PATCH の更新を許可しますが、MAJOR は許可しません。^4.17.214.17.21 から 5.0.0 未満までを受け入れます。0.x リリースについては、キャレットレンジはより制限的です: ^0.2.30.3.0 未満の更新を許可し、すべての 0.x バージョンを許可するわけではありません。
  • ~(チルダ) — マイナーバージョンが指定された場合に PATCH の更新を許可します。~1.6.01.6.x を受け入れますが、1.7.0 は受け入れません。
  • 完全一致バージョン18.2.0 はその特定のバージョンのみをインストールします。

npm install を実行したときの npm のデフォルトはキャレットです。これにより、バグ修正や新機能を自動的に取得しつつ、破壊的変更から保護されます——ただし、パッケージ作者が SemVer を正しく遵守していることが前提です。その前提が常に成り立つわけではありません。

ロックファイルが重要な理由

package-lock.json は、特定の時点でインストールされた正確なバージョンを記録します。^4.17.21 のようなレンジが新しいバージョンを許可していても、ロックファイルはチームと CI 環境で実際に使用されるバージョンを固定します。これが、再現可能なビルドのためにロックファイルをコミットすることが重要である理由です。

0.x リリースとプリリリースバージョンを理解する

開発者を不意打ちすることが多い領域が 2 つあります:

0.x リリースは定義上、不安定です。 0.4.2 のパッケージは互換性の保証をしません。0.4.20.5.0 の間では何でも変更され得ます。まだ 1.0.0 に達していないパッケージについては、SemVer の互換性ルールに依存しないでください。

1.0.0-beta.1 のようなプリリリースバージョンは、安定版リリースよりも優先順位が低くなります。 明示的に要求しない限り、npm はプリリリースバージョンをインストールしません。^1.0.0 のような通常のレンジは、自動的に 1.1.0-beta.1 に解決されることはありません。これにより、誤って不安定なコードを取り込むことから保護されます。

どのバージョンを上げるべきタイミング

パッケージをメンテナンスしている場合は、以下をガイドとして使用してください:

変更の種類上げるバージョン
破壊的な API 変更MAJOR1.4.22.0.0
後方互換性のある新機能MINOR1.4.21.5.0
バグ修正のみPATCH1.4.21.4.3
機能の非推奨化(削除なし)MINOR1.4.21.5.0

MINOR を上げる際には、PATCH をゼロにリセットします。MAJOR を上げる際には、MINOR と PATCH の両方をゼロにリセットします。

SemVer は契約であり、保証ではない

SemVer は変更を伝えるための共通言語を提供します。しかし、メンテナーがパッチリリースで破壊的変更を出荷することを技術的に防ぐものではありません。semantic-release のようなツールは、コミットメッセージに基づいてバージョニングを自動化でき、手作業によるミスを減らし、チームが SemVer 規約をより一貫して遵守できるようサポートします。

まとめ

SemVer のレンズを通して npm のバージョニングとパッケージのバージョニングを理解することで、オープンソースパッケージのより自信ある利用者となり、また自分のパッケージのより責任あるパブリッシャーとなれます。フォーマットはシンプルですが、その意味は深く広がっています: すべての桁が意図を伝え、すべてのレンジ演算子がリスクを形作り、すべてのロックファイルが再現性を守ります。SemVer を、それが設計された通りの共有語彙として扱えば、依存関係の管理は目に見えて穏やかになるでしょう。

よくある質問

本来安全であるべき更新(パッチやマイナーアップなど)を通じて破壊的変更を受け取る可能性があります。自分自身を保護するためには、package-lock.json をコミットし、アップグレード前に変更履歴を確認し、バージョンアップと共にリリースノートを表示する Renovate や Dependabot のようなツールの使用を検討してください。重要な依存関係については、正確なバージョンを固定することは合理的な防御策です。

キャレットは npm のデフォルトであり、メジャーバージョン内のマイナーおよびパッチ更新を許可するため、ほとんどのアプリケーションで適切に機能します。チルダはより厳密で、パッチ更新のみを受け入れるため、新機能よりも安定性を優先するプロジェクトに適しています。公開するライブラリについては、利用者が後方互換性のある改善から自動的に恩恵を受けられるよう、キャレットレンジを優先してください。

SemVer 仕様では、1.0.0 未満は初期開発と見なされ、公開 API は安定したものとして扱うべきではないと明示的に述べられています。メンテナーは、メジャー番号を上げることなく、任意の 0.x リリース間で破壊的変更を導入できます。プロジェクトが 1.0.0 に達すると、SemVer の完全な互換性ルールにコミットすることになります。

正確なバージョンを指定する(npm install package@1.0.0-beta.1)か、タグを使用する(npm install package@next)ことで、明示的に要求する必要があります。^1.0.0 のような標準レンジはプリリリースバージョンを完全にスキップするため、本番環境で不安定なコードが誤ってインストールされるのを防ぎます。

Gain control over your UX

See how users are using your site as if you were sitting next to them, learn and iterate faster with OpenReplay. — the open-source session replay tool for developers. Self-host it in minutes, and have complete control over your customer data. Check our GitHub repo and join the thousands of developers in our community.

OpenReplay