跳到主要内容

语义化版本号怎么递增:major.minor.patch 进哪一位说清楚

讲清语义化版本号三位数字各管什么,破坏性改动进 major、新功能进 minor、缺陷修复进 patch,预发布标签 alpha/beta/rc 怎么排,以及 npm 发版时该取哪一档。

发布于 作者 李雷
#semver #版本号 #npm #发版

语义化版本号怎么递增:major.minor.patch 进哪一位说清楚

每次发版前,版本号到底往哪一位加,是很多人含糊带过的一步。语义化版本(SemVer)给的答案其实很死板:版本号是 major.minor.patch 三个数字,每一位都有明确分工,你改了什么,就决定哪一位加一。把规则记牢,版本号就不再是拍脑袋的产物,而是对使用方的一句承诺。

三位数字各管什么

1.2.3 拆开看:1 是主版本号 major,2 是次版本号 minor,3 是修订号 patch。它们从左到右,代表升级风险从大到小。

  • patch(修订号):向后兼容的缺陷修复。别人升上来不用改任何代码。
  • minor(次版本号):向后兼容地新增功能。旧用法照常能跑,只是多了新能力。
  • major(主版本号):破坏性改动。删了接口、改了参数、换了默认行为,使用方升级必须动手适配。

一条铁律:破坏性改动进 major,新功能进 minor,缺陷修复进 patch。 而且高位一加,低位要归零。minor 加一,patch 清零;major 加一,minor 和 patch 都清零。所以 1.2.3 加 minor 不是 1.3.3,而是 1.3.0

一个具体例子:1.2.3 加完会变成什么

假设你手头是 1.2.3,这一次到底该发哪个号?

  • 只修了一个缺陷,没动任何接口:取 patch,发 1.2.4
  • 加了一个新 API,老代码完全不受影响:取 minor,发 1.3.0
  • 删掉了一个废弃方法,或者改了某个函数的返回结构:取 major,发 2.0.0

注意 patch 那一位是数字不是文本。1.2.9 修一个 bug 是 1.2.10,不是 1.2.91。这是新手最容易踩的坑之一:把版本段当字符串拼,而不是当整数进位。

预发布标签:alpha、beta、rc 怎么排

大版本正式发布前,通常想先放个测试版收反馈,这就是预发布(pre-release)。它挂在版本号后面,用连字符接上一个标识加计数,比如 2.0.0-beta.0

常见的标识有三档,语义上由粗到细:

  • alpha:内部尝鲜,功能可能还缺胳膊少腿。
  • beta:功能基本齐了,找外部测试者试用。
  • rc(release candidate,候选版本):自认为可以发了,只等最后验证。

预发布版本永远低于对应的正式版,所以 2.0.0-rc.1 排在 2.0.0 前面。计数也按数字走:beta.9 的下一个是 beta.10,不是 beta.91。还有个容易忽略的细节:1.2.4-0 这种带预发布的版本,做一次稳定 patch 递增会消解1.2.4,而不是跳到 1.2.5,因为这个预发布本来就是冲着 1.2.4 来的。

npm 发版时怎么落地

在 npm 生态里,npm version major|minor|patch 会改 package.json 并打一个 git tag。还有 premajorpreminorprepatchprerelease 四种预发布递增,配合 --preid=beta 就能产出 2.0.0-beta.0 这样的号。

我自己发包时养成一个习惯:动手敲 npm version 之前,先把当前版本号填进 语义化版本号递增工具,八种递增结果一次列全,直接对着挑那一档,省掉心算,也避免把 1.4.10 当成 1.4.3 发出去。切候选版本时设上 rc 标识,读 premajor 那一行就是 2.0.0-rc.0,发出去收完反馈再把 prerelease 行递增到 2.0.0-rc.1,一轮轮推到最后取纯 major 的 2.0.0

如果手上有两个版本号拿不准谁新谁旧,再配一个 语义化版本号比较工具 核对一下,预发布和正式版的先后顺序就不会搞错。

小结

语义化版本不是装饰,是一份写给使用方的契约:看版本号就知道这次升级要不要担心。记住三句话就够用,破坏性进 major,功能进 minor,修复进 patch,预发布用 alpha/beta/rc 排在正式版前面。把这套规则交给工具去算,你只管对着改动挑档位,发版这一步就再也不用犹豫。


Made by Toolora · Updated 2026-06-13