1.0.0-rc.1 と 1.0.0 はどちらが上か:SemVer のプレリリースの順序と ^ 範囲
1.0.0-rc.1 と 1.0.0 のどちらが上か、^1.2.3 が 1.5.0-beta.1 を選ばない理由を SemVer 2.0.0、node-semver、Cargo の文書から説明します。
1.0.0-rc.1 と 1.0.0 では、どちらの優先順位が高いのでしょうか。依存関係を ^1.2.3 と書いたとき、1.5.0-beta.1 が候補に入らないのはなぜでしょうか。
この2つは別の層で決まります。バージョンの優先順位は Semantic Versioning(SemVer)2.0.0 が定めます。^1.2.3 のような範囲やプレリリースを含める条件は、パッケージ管理ツールが定めます。
通常のバージョンは数値として比べる
通常の SemVer は X.Y.Z の形です。各部分は負でない整数で、先頭に 0 を付けません。優先順位はメジャー、マイナー、パッチを左から数値として比べ、最初に違いが出たところで決まります。
そのため 1.10.0 は 1.9.0 より上です。文字列としてソートすると逆の順序になることがあるので、バージョンの一覧には SemVer の比較関数を使います。
ハイフンの後ろはプレリリース
パッチ番号の後ろにハイフンと識別子を付けると、プレリリースバージョンになります。
1.0.0-alpha
1.0.0-beta.2
1.0.0-rc.1
メジャー、マイナー、パッチが同じなら、プレリリースは通常バージョンより低くなります。
1.0.0-rc.1 < 1.0.0
プレリリース同士は、ドットで区切った識別子を左から比べます。数字だけの識別子は数値として比べ、それ以外は ASCII の順で辞書式に比べます。数字の識別子は数字でない識別子より低くなります。途中まで同じなら、識別子が多いほうが上です。
SemVer の仕様には次の例があります。
1.0.0-alpha
< 1.0.0-alpha.1
< 1.0.0-alpha.beta
< 1.0.0-beta
< 1.0.0-beta.2
< 1.0.0-beta.11
< 1.0.0-rc.1
< 1.0.0
beta.2 が beta.11 より低いのは、2 と 11 が別々の数字の識別子だからです。一方、rc9 と rc10 はそれぞれ1つの英数字識別子です。文字の順では rc10 が rc9 より低くなります。番号が2桁になる可能性があるなら、rc.9、rc.10 のようにドットで分けたほうが数値としての意図が明確です。
ビルドメタデータは優先順位に影響しない
+ の後ろにはビルドメタデータを付けられます。
1.0.0+build.1
1.0.0+build.2
SemVer は優先順位を決めるときにビルドメタデータを無視します。この2つはビルドの表記が異なっていても、優先順位は同じです。
^1.2.3 がプレリリースを選ばない理由
SemVer の仕様には ^1.2.3 のような範囲の文法はありません。範囲はツールごとに定義されます。
npm が使う node-semver では、^1.2.3 は次の範囲に展開されます。
>=1.2.3 <2.0.0-0
2.0.0-0 は、有効な 2.0.0 のプレリリースのうち最も低い値です。この上限によって、2.0.0 のプレリリースも範囲から外れます。
ただし、これだけでは 1.5.0-beta.1 が除外される理由を説明できません。優先順位だけを見れば、このバージョンは上下の境界の間にあります。node-semver には別の規則があり、同じ [major, minor, patch] を持つプレリリース付きの比較条件が範囲内にある場合だけ、そのプレリリースを既定で含めます。
結果は次のとおりです。
1.5.0-beta.1 satisfies ^1.2.3 → false
1.2.3-beta.4 satisfies ^1.2.3-beta.2 → true
1.2.4-beta.2 satisfies ^1.2.3-beta.2 → false
1.3.0 satisfies ^1.2.3-beta.2 → true
includePrerelease オプションを使うと、node-semver の既定のプレリリース除外を変更できます。ただし、範囲に明記された上限と下限まで無視するものではありません。
Cargo は似ているが、同じ規則ではない
Cargo も、依存関係の要件にプレリリースを明記しない限り、プレリリースを除外します。1.0.0-alpha だけが公開されている場合、foo = "1.0" に一致するバージョンはありません。
foo = "1.0.0-alpha" と書くと、同じ 1.0.0 系列の 1.0.0-beta、通常版の 1.0.0、互換性のある通常版 1.2.0 へ更新できます。一方、1.0.1-alpha や 1.0.1-beta には更新しません。
プレリリースを範囲から除外するのは SemVer 自体の規則ではなく、各ツールの方針です。別のパッケージマネージャーを使う場合は、そのツールの範囲に関する文書を確認する必要があります。
参照した仕様とドキュメント
- Semantic Versioning 2.0.0
- node-semver README:
Caret Ranges、Prerelease Tags - The Cargo Book — Specifying Dependencies: Pre-releases
リンクと内容は2026年10月1日に確認しました。