# npm - 管理项目版本号

# 遇到问题

在使用 npm 管理项目的时候,package.json 里面都有一个版本号。需要修改的时候,都是怎么操作的呢?可别再是手动修改了。npm 已经提供了非常方便的命令。

# 解决方案

# npm 命令

命令行输入 npm version -h,可以看到:

npm version -h
# npm version [<newversion> | major | minor | patch | premajor | preminor | prepatch | prerelease [--preid=<prerelease-id>] | from-git] (run in package dir)
# 'npm -v' or 'npm --version' to print npm version (6.4.1)
# 'npm view <pkg> version' to view a package's published version
# 'npm ls' to inspect current package/dependency versions

1
2
3
4
5
6

后面的参数可以看到,支持直接指定新版本,或者指定升级版本,先行版,测试版等。

举例说明🌰

假如我们现在的版本号是 version: 1.0.0,下面我们依次运行下面代码

npm version major // 主版本号:当你做了不兼容的API修改
# v2.0.0

npm version minor // 次版本号:当你做了向下兼容的功能性新增
# v2.1.0

npm version patch // 修订号:当你做了向下兼容的问题修正
# v2.1.1

npm version premajor // 预备主版本
# v3.0.0-0

npm version preminor // 预备次版本
# v3.1.0-0

npm version prepatch // 预备修订版本
# v3.1.1-0

npm version prerelease // 预发布版本
# v3.1.1-1

npm version prerelease --preid=alpha // 命名先行版,测试版用beta
# v3.1.1-alpha.0

npm version prerelease // 升级先行版
# v3.1.1-alpha.1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

补充说明,运行 npm version 的时候,本地 git status 需要是 clear 的。因为运行命令之后会自动提交一个 commit 并打上 tag

也可以自定义 commit message。比如:

npm version patch -m "升级到 %s: 演示自定义msg"
# v3.1.1
1
2

message 中的 s% 将会被替换为版本号。

npm-version

# 版本号策略

我们需要根据改动来选择升级对应版本号。 版本号格式:主版本号.次版本号.修订号:

  • 主版本号:当你做了不兼容的 API 修改;
  • 次版本号:当你做了向下兼容的功能性新增;
  • 修订号:当你做了向下兼容的问题修正;
  • 预发布版本号:还没有正式发布的版本

版本号只能增加,禁止下降,代码的修改必须以新版形式更新。

特别是当你的代码已经是正式环境,而且有使用者依赖。升级的时候就需要仔细的注意不兼容性问题。

# 使用指南

在 package.json 文件里面使用的时候,可以使用特殊符号来表明依赖的版本范围。语义化版本范围规定:

  • ~:只升级修订号
  • ^:升级次版本号和修订号
  • *:升级到最新版本

# 版本含义

  • 小于 1.0.0:测试版,说明该库目前 API 不稳定
  • 大于等于 1.0.0:正式版
  • 版本中携带 alpha、beta、rc 等 tag 字样,统称先行版,带有预发布版本号的,一般格式为 x.y.z-[tag].[次数 / meta 信息]
    • alpha:内部版本
    • beta:公测版本
    • rc:预发的正式版本

# 真实案例🌰

Node version requires at least 10 (opens new window)

issue 截图:

mkdirp-version

背景这样的,项目里面依赖了 js-beautify@^1.10.3 这个仓库,然后它又依赖了 mkdirp@~0.5.1

然后,mkdirp 的作者在前不久更新了对 nodejs 版本的依赖,从 node@8 -> node@10。并升级版本到 mkdirp@1.0.0 package updates (opens new window)

提交记录截图:

mkdirp-update

然后,js-beautify 升级到 1.11.x 的时候,顺便也升级了 mkdirp@~1.0.3

然后 js-beautify 这次升级的是次版本号,所以在安装依赖的时候就会安装 js-beautify@1.11.x,进而安装 mkdirp@~1.0.3

最后,对 nodejs 版本的依赖也就变成了 node@10。就会提示

error mkdirp@1.0.4: The engine "node" is incompatible with this module. Expected version ">=10". Got "8.x"
1

因为运行环境安装的还是 node@8,可能有同学就说那就升级一下 node 版本就好了。如果是我们本地开发环境,当然很 easy , n/nvm 都可以方便管理 node 版本。但是这个报错是在公司的 CI 服务器上,就很尴尬了。因为上面跑了很多项目,也没法说想升级就升级。

临时办法总还是有的,那就是 yarn.lock/package-lock.json 里面锁定版本。js-beautify to 1.10.3, mkdirp to 0.5.5

最后最后,我觉得 isaacs 在升级 node 依赖的时候的推特说的挺有道理的。因为 node@8 停止更新有段时间了,所以升级 node@10 ,后面评论里还补充了一句下次 node@10 停止的时候,又会再次考虑升级。

推文截图:

mkdirp-tt


让我想到了 某E ,我们应该支持这种升级。 mkdirp-ie

# 管理 tag

首先需要区分一下,npm 和 git 的 tag。

# git 的 tag

如果你达到一个重要的阶段,并希望永远记住那个特别的提交快照,你可以使用 git tag 给它打上标签。比如说版本更新发布的时候。使用 npm version prepatch 之后,上文提到了会再执行一个 git tag ${version},这个 tag 就是 git 的。我们也可以手动提交,git tag -a <tag名> -m <msg>,推送 tag 到远程仓库 git push --tags origin master

# npm 的 tag

npm 也有 tag 的概念。因为leftpad事件 (opens new window) npm version 发布之后只有在24小时内才允许撤销发布的包,撤销之后不能再发布和撤销的包名称版本相同的包。所以我们可以使用 tag 给发布操作增加一些保险。比如我们需要发布一个测试版本,但又不希望普通用户下载到这个版本。 使用 npm dist-tag ls [<pkg>] 可以查看一个 npm 包的 tag。

npm dist-tag ls git-webhook-handler
# beta: 1.0.6-beta
# latest: 1.0.6
1
2
3

可以看到两个版本信息。这样正常 npm install git-webhook-handler 的时候就会下载到 1.0.6 版本的。如果我们要下载 beta 版,则可以使用 npm install git-webhook-handler@beta

因此如果手滑,npm publish 了一个先行版或者测试版本:

npm dist-tag ls git-webhook-handler
# beta: 1.0.6-beta.1
# latest: 1.0.6-beta.2
1
2
3

这个时候,就可以赶紧切换 tag ,把 latest 回退到稳定版本就可以了

npm dist-tag add git-webhook-handler@1.0.6 latest
# +latest: git-webhook-handler@1.0.6
1
2

再也不用担心手滑背锅了。

# 查看发行版本

npm view git-webhook-handler versions
# [ '1.0.0', '1.0.1', '1.0.2', '1.0.3', '1.0.4', '1.0.5', '1.0.6' ]
1
2

可以查看 git-webhook-handler 发布过的所有版本号。去掉 s 也可以使用。

# 参考

上次更新: 3/19/2021, 11:28:07 AM