Appearance
npm 版本控制
npm版本控制是软件开发中的重要环节,涉及包的版本管理、发布流程和语义化版本规范。本章将详细介绍npm版本控制的各个方面。
语义化版本控制 (SemVer)
语义化版本控制是npm采用的版本管理规范,格式为 MAJOR.MINOR.PATCH:
- MAJOR: 主版本号 - 包含不兼容的API变更
- MINOR: 次版本号 - 向后兼容的功能添加
- PATCH: 修订号 - 向后兼容的bug修复
版本号递增规则
bash
# 假设当前版本是 1.2.3
# 修复bug,向后兼容
npm version patch # 结果: 1.2.4
# 添加功能,向后兼容
npm version minor # 结果: 1.3.0
# 不兼容变更
npm version major # 结果: 2.0.0
# 预发布版本
npm version prerelease --preid=alpha # 结果: 2.0.0-alpha.0
npm version prerelease --preid=beta # 结果: 2.0.0-beta.0
npm version prerelease --preid=rc # 结果: 2.0.0-rc.0
预发布版本
预发布版本用于测试和开发:
json
{
"version": "2.0.0-alpha.1",
"version": "2.0.0-beta.2",
"version": "2.0.0-rc.1"
}
预发布版本排序规则: 2.0.0-alpha.1 < 2.0.0-beta.1 < 2.0.0-rc.1 < 2.0.0
npm version命令详解
基本用法
bash
# 查看当前版本
npm version
# 递增版本号
npm version patch # 1.0.0 -> 1.0.1
npm version minor # 1.0.1 -> 1.1.0
npm version major # 1.1.0 -> 2.0.0
# 设置特定版本
npm version 1.2.3
# 预发布版本
npm version premajor --preid=alpha # 1.0.0 -> 2.0.0-alpha.0
npm version preminor --preid=beta # 1.0.0 -> 1.1.0-beta.0
npm version prepatch --preid=rc # 1.0.0 -> 1.0.1-rc.0
自定义版本消息
bash
# 设置自定义git提交消息前缀
npm version patch --message "Release version %s"
# 跳过git提交和标签
npm version patch --no-git-tag-version
# 预览而不执行
npm version patch --dry-run
版本钩子
npm version命令会触发以下钩子:
json
{
"scripts": {
"preversion": "npm test", # 版本递增前执行
"version": "echo 'Version updated'", # 版本递增时执行
"postversion": "git push && git push --tags" # 版本递增后执行
}
}
版本范围和依赖管理
版本范围符号
json
{
"dependencies": {
// 允许补丁和次版本更新
"lodash": "^4.17.21",
// 只允许补丁版本更新
"express": "~4.18.1",
// 固定版本
"react": "18.2.0",
// 大于等于
"node": ">=16.0.0",
// 小于
"old-package": "<2.0.0",
// 范围
"package": ">=1.0.0 <2.0.0",
// 连字符范围
"package": "1.2.3 - 2.3.4",
// 通配符
"package": "1.x.x",
"package": "1.2.x",
// 或操作符
"package": "1.2.3 || >=1.5.0 <2.0.0"
}
}
版本范围最佳实践
json
{
"dependencies": {
// 生产依赖使用^确保安全更新
"express": "^4.18.0",
// 框架相关依赖使用精确版本或~
"react": "^18.0.0",
"react-dom": "^18.0.0",
// 开发依赖可以使用*或^
"webpack": "^5.72.0"
},
"devDependencies": {
// 测试框架等开发依赖
"jest": "^28.0.0"
}
}
发布流程
准备发布
bash
# 1. 确保所有测试通过
npm test
# 2. 检查代码质量
npm run lint
npm run build
# 3. 检查安全漏洞
npm audit
# 4. 确保所有文件都包含在发布中
npm pack --dry-run
发布命令
bash
# 登录npm
npm login
# 验证当前用户
npm whoami
# 发布包
npm publish
# 发布预发布版本
npm publish --tag next
npm publish --tag beta
npm publish --tag alpha
# 发布特定版本
npm publish --tag latest # 默认标签
预发布流程
bash
# 1. 递增到预发布版本
npm version prerelease --preid=beta
# 2. 发布到beta标签
npm publish --tag beta
# 3. 用户安装预发布版本
npm install package-name@beta
版本标签管理
使用标签
bash
# 查看所有标签
npm dist-tag ls package-name
# 添加标签
npm dist-tag add package-name@1.0.0 latest
npm dist-tag add package-name@2.0.0-beta.1 beta
# 删除标签
npm dist-tag rm package-name beta
# 安装特定标签版本
npm install package-name@beta
npm install package-name@next
常见标签
latest: 默认标签,用户不指定版本时安装next: 下一个稳定版本的候选beta: 测试版本alpha: 早期测试版本rc: 发布候选版本
工作区版本管理
统一版本管理
json
{
"name": "my-workspace",
"private": true,
"workspaces": [
"packages/*"
],
"scripts": {
"version:all": "npm version --workspaces",
"publish:all": "npm publish --workspaces"
}
}
独立版本管理
bash
# 为特定工作区递增版本
npm version patch --workspace=package-a
# 为所有工作区递增版本
npm version patch --workspaces
# 发布所有工作区
npm publish --workspaces
版本策略
依赖版本策略
json
{
"engines": {
"node": ">=16.0.0",
"npm": ">=8.0.0"
},
"volta": {
"node": "18.12.1",
"npm": "8.19.2"
}
}
弃用版本
bash
# 弃用特定版本
npm deprecate package-name@"<1.0.0" "This version is deprecated, please upgrade"
# 弃用所有版本
npm deprecate package-name "This package is deprecated"
# 取消弃用(重新发布包)
npm publish
版本历史管理
查看版本历史
bash
# 查看包的所有版本
npm view package-name versions --json
# 查看特定版本信息
npm view package-name@1.0.0
# 查看包的详细信息
npm view package-name --json
回滚版本
bash
# 降级到特定版本
npm install package-name@1.0.0
# 查看版本历史
npm view package-name time
版本兼容性
向后兼容性
json
{
"peerDependencies": {
// 确保兼容的React版本
"react": "^16.8.0 || ^17.0.0 || ^18.0.0"
},
"peerDependenciesMeta": {
"typescript": {
"optional": true
}
}
}
引擎兼容性
json
{
"engines": {
"node": ">=16.0.0",
"npm": ">=8.0.0"
},
"os": ["darwin", "linux", "win32"],
"cpu": ["x64", "arm64"]
}
自动化版本管理
使用标准版本工具
bash
# 安装standard-version
npm install --save-dev standard-version
# 配置package.json
{
"scripts": {
"release": "standard-version"
}
}
# 使用
npm run release -- --release-as major
npm run release -- --release-as minor
npm run release -- --release-as patch
npm run release -- --prerelease alpha
conventional-changelog
bash
# 安装工具
npm install --save-dev conventional-changelog-cli
# 生成changelog
npx conventional-changelog -p angular -i CHANGELOG.md -s
# 发布脚本
{
"scripts": {
"release": "conventional-changelog -p angular -i CHANGELOG.md -s && git add CHANGELOG.md"
}
}
版本控制最佳实践
版本递增策略
json
{
"scripts": {
// 自动化发布流程
"preversion": "npm test",
"version": "conventional-changelog -p angular -i CHANGELOG.md -s && git add CHANGELOG.md",
"postversion": "git push && git push --tags && npm publish"
}
}
版本验证
bash
# 检查版本格式
npm version | grep -E '^[0-9]+\.[0-9]+\.[0-9]+$'
# 验证package.json版本字段
node -e "console.log(require('./package.json').version.match(/^\d+\.\d+\.\d+$/) ? 'Valid' : 'Invalid')"
多环境版本管理
json
{
"version": "1.0.0",
"scripts": {
"version:staging": "npm version prerelease --preid=staging",
"version:prod": "npm version patch",
"release:minor": "npm version minor && npm publish",
"release:major": "npm version major && npm publish"
}
}
故障排除
版本冲突解决
bash
# 检查版本冲突
npm ls package-name
# 强制使用特定版本
npm install package-name@1.2.3 --save
# 使用overrides解决冲突 (npm 8.3+)
{
"overrides": {
"conflicting-dep": "$conflicting-dep"
}
}
发布问题
bash
# 检查发布的文件
npm pack --dry-run
# 验证package.json
npm run prepublishOnly
# 查看发布配置
npm config list
通过遵循这些版本控制最佳实践,您可以确保包的版本管理清晰、可预测,并与SemVer规范保持一致。