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 の文書から説明します。

開発バージョン管理SemVer依存関係

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 自体の規則ではなく、各ツールの方針です。別のパッケージマネージャーを使う場合は、そのツールの範囲に関する文書を確認する必要があります。

参照した仕様とドキュメント

リンクと内容は2026年10月1日に確認しました。

ブログへ