calc / semver

Semver ツール

セマンティックバージョニング(SemVer)のバージョン比較・バンプ・レンジチェックをブラウザ上で実行します。 外部ライブラリなしの純粋な JavaScript 実装。入力データはサーバーに送信されません。

vs
バージョン A と B を入力すると比較結果が表示されます

使い方

01
  1. バージョン比較: 2つのバージョンを入力し、大小関係(新しい・古い・等値)を確認します
  2. バージョンバンプ: 現在のバージョンと major / minor / patch を選択すると次のバージョンを算出します
  3. レンジチェック: バージョンとレンジ(^~・比較演算子)を入力し、そのバージョンがレンジを満たすかを確認します
  4. バージョンには v プレフィックスも入力可能です(例: v1.2.3
  5. pre-release 識別子にも対応しています(例: 1.0.0-alpha.1

実装コード

02

コアロジックは標準の文字列操作と正規表現のみで実装しています。semver パッケージなどの外部ライブラリは不要。 そのままコピーしてプロジェクトで利用できます。

export type SemVer = { major: number; minor: number; patch: number; pre?: string }

export function parseSemVer(v: string): SemVer | null {
  const match = v.trim().replace(/^v/, '').match(
    /^(\d+)\.(\d+)\.(\d+)(?:-([a-zA-Z0-9.\-]+))?$/
  )
  if (!match) return null
  return {
    major: parseInt(match[1], 10),
    minor: parseInt(match[2], 10),
    patch: parseInt(match[3], 10),
    pre: match[4],
  }
}

export function compareSemVer(a: string, b: string): -1 | 0 | 1 {
  const pa = parseSemVer(a)
  const pb = parseSemVer(b)
  if (!pa || !pb) return 0
  if (pa.major !== pb.major) return pa.major < pb.major ? -1 : 1
  if (pa.minor !== pb.minor) return pa.minor < pb.minor ? -1 : 1
  if (pa.patch !== pb.patch) return pa.patch < pb.patch ? -1 : 1
  // pre-release なし > pre-release あり (SemVer 仕様)
  if (!pa.pre && !pb.pre) return 0
  if (!pa.pre) return 1
  if (!pb.pre) return -1
  return pa.pre < pb.pre ? -1 : pa.pre > pb.pre ? 1 : 0
}

export function bumpVersion(v: string, type: 'major' | 'minor' | 'patch'): string {
  const parsed = parseSemVer(v)
  if (!parsed) return v
  const { major, minor, patch } = parsed
  switch (type) {
    case 'major': return `${major + 1}.0.0`
    case 'minor': return `${major}.${minor + 1}.0`
    case 'patch': return `${major}.${minor}.${patch + 1}`
  }
}

export function satisfiesRange(version: string, range: string): boolean {
  const v = parseSemVer(version)
  if (!v) return false
  const trimmedRange = range.trim()

  // ^x.y.z: >=x.y.z <(x+1).0.0
  const caretMatch = trimmedRange.match(/^\^(.+)$/)
  if (caretMatch) {
    const min = parseSemVer(caretMatch[1])
    if (!min) return false
    return compareSemVer(version, caretMatch[1]) >= 0 && v.major === min.major
  }

  // ~x.y.z: >=x.y.z <x.(y+1).0
  const tildeMatch = trimmedRange.match(/^~(.+)$/)
  if (tildeMatch) {
    const min = parseSemVer(tildeMatch[1])
    if (!min) return false
    return (
      compareSemVer(version, tildeMatch[1]) >= 0 &&
      v.major === min.major &&
      v.minor === min.minor
    )
  }

  // >=, >, <=, <, =
  const opMatch = trimmedRange.match(/^(>=|>|<=|<|=)(.+)$/)
  if (opMatch) {
    const cmp = compareSemVer(version, opMatch[2].trim())
    switch (opMatch[1]) {
      case '>=': return cmp >= 0
      case '>':  return cmp > 0
      case '<=': return cmp <= 0
      case '<':  return cmp < 0
      case '=':  return cmp === 0
    }
  }

  return compareSemVer(version, trimmedRange) === 0
}

よくある使用例・注意点

03
npm パッケージの依存バージョンを確認したい
package.json の dependencies には ^ や ~ のようなレンジが書かれています。このツールのレンジチェックモードで、インストールされたバージョンが指定範囲に含まれるかをすぐに確認できます。
リリース時のバージョン番号を決める
バグ修正のみなら patch、後方互換な新機能追加なら minor、破壊的変更なら major をバンプします。バンプモードに現在のバージョンを入力するだけで次のバージョン候補が即座に表示されます。
pre-release バージョンの扱い
SemVer 仕様では 1.0.0-alpha は 1.0.0 より「古い」と見なされます(pre-release なし > pre-release あり)。このツールも同じ仕様に準拠しています。バンプ時は pre-release 識別子が除去されます。
^ と ~ の違い
^1.2.3 は major が一致する最新まで(1.2.3 以上 2.0.0 未満)を許容します。~1.2.3 はより厳しく、major と minor が一致する最新まで(1.2.3 以上 1.3.0 未満)のみ許容します。
対応していないレンジ構文
このツールは単一のレンジ条件に対応しています。npm の >=1.0.0 <2.0.0 のような複数条件の AND 結合や、ハイフン範囲(1.0.0 - 2.0.0)、ワイルドカード(1.x)は未対応です。

関連ツール

04
Gitコミットメッセージ生成cron式パーサー正規表現テスター

ソースコード

05

このツールのソースコード(テストコードを含む)はGitHubで公開しています。 MITライセンスで自由に利用・改変できます。

GitHub でコードを見る →