11.1.1 SemVer 规范:主版本/次版本/修订版本
一句话破题
**语义化版本(SemVer)**是一套版本号命名规范,格式为 主版本.次版本.修订版本,每个数字的变化都传达了特定的含义。
核心价值
理解 SemVer 能让你:
- 正确判断依赖升级的风险
- 为自己的项目设置合理的版本号
- 与团队和用户建立明确的版本契约
三个数字的含义
1.2.3
│ │ └── 修订版本(Patch):修复 Bug,向后兼容
│ └──── 次版本(Minor):新功能,向后兼容
└────── 主版本(Major):破坏性变更,不向后兼容| 版本变化 | 含义 | 用户需要做什么 |
|---|---|---|
1.0.0 → 1.0.1 | 修复了 Bug | 放心升级 |
1.0.0 → 1.1.0 | 新增了功能 | 放心升级,可使用新功能 |
1.0.0 → 2.0.0 | 有破坏性变更 | 需要阅读升级指南 |
快速上手
在 package.json 中设置版本
json
{
"name": "my-app",
"version": "1.2.3"
}使用 npm 命令更新版本
bash
# 修复 Bug:1.2.3 → 1.2.4
npm version patch
# 新增功能:1.2.3 → 1.3.0
npm version minor
# 破坏性变更:1.2.3 → 2.0.0
npm version major预发布版本
bash
# 1.2.3 → 1.2.4-alpha.0
npm version prerelease --preid=alpha
# 1.2.3 → 1.2.4-beta.0
npm version prerelease --preid=beta
# 1.2.3 → 1.2.4-rc.0
npm version prerelease --preid=rc特殊规则
0.x.x 版本
0.x.x 版本表示项目仍在初期开发阶段,API 可能随时变化:
0.1.0 ─→ 初始开发版本
0.2.0 ─→ 可能有破坏性变更
0.2.1 ─→ Bug 修复
1.0.0 ─→ 第一个稳定版本版本号比较
typescript
// 比较版本号的简单实现
function compareVersions(a: string, b: string): number {
const [aMajor, aMinor, aPatch] = a.split('.').map(Number)
const [bMajor, bMinor, bPatch] = b.split('.').map(Number)
if (aMajor !== bMajor) return aMajor - bMajor
if (aMinor !== bMinor) return aMinor - bMinor
return aPatch - bPatch
}
compareVersions('1.2.3', '1.2.4') // -1(a < b)
compareVersions('2.0.0', '1.9.9') // 1(a > b)依赖版本范围
在 package.json 中,可以指定依赖的版本范围:
| 符号 | 含义 | 示例 |
|---|---|---|
^ | 允许次版本和修订版本更新 | ^1.2.3 → 1.x.x |
~ | 只允许修订版本更新 | ~1.2.3 → 1.2.x |
| 无符号 | 锁定精确版本 | 1.2.3 → 只用 1.2.3 |
json
{
"dependencies": {
"react": "^18.2.0", // 18.2.0 ~ 18.x.x
"lodash": "~4.17.21", // 4.17.21 ~ 4.17.x
"typescript": "5.3.2" // 精确锁定
}
}避坑指南
新手最容易犯的错
- 在
1.x.x版本引入破坏性变更但不升主版本号 - 忘记在发布前更新版本号
- 手动修改
package.json而不用npm version - 不理解
^和~的区别导致意外升级
