分享我的发现、想法与心得

0%

使用npm命令行更新版本号

hero-img

背景

版本号是用于逐步演进软件的过程中和其使用者之间订立的一套公共规则,Semantic Versioning 语义化版本号则是版本号具体如何约定的一套公共约定。我们在日常的软件生产过程中,不单只产出软件本身,还会产出一些可供复用的代码包。这些代码包糅合集成在一起从而产出一个完整的软件及系统,期间代码包依旧会继续研发添加新特性或是修复旧有问题。在这个趋势之下,基于语义化版本号规则就能更好的细化软件生产及迭代,使软件资产能有序地更新及发布。

1
2
3
版本号基本是由三位数字组成:
1 . 0 . 0
[MAJOR].[MINOR].[PATCH]

三位数字分别代表不同意思:

  • MAJOR 进行不兼容的API更改时的版本
  • MINOR 以向后兼容的方式添加功能时的版本
  • PATCH 向后兼容的错误修复程序的版本

具体内容建议去详细查看 Semantic Versioning 语义化版本号 公约。

问题

团队将部分人手操作交付给CI/CD工具,比如此文讨论的软件发布的版本的问题。目前软件发布过程是基于人手直接修改package.json文件中的version字段来实现版本的更新。在前端开始模块化管理各种公共模块后,将会产出大量的代码包需要维护。把一些人为的操作交付给机器,让机器帮助前端同事解决部分重复的工作,也能有效减少这些环节中的人为错误。

解决办法

前端目前的代码包管理工具npm,本身有提供命令工具帮助编码人员解决版本升级的工作。下面是代码:

1
2
3
4
5
$ npm version [<newversion> | major | minor | patch | premajor | preminor | prepatch | prerelease [--preid=<prerelease-id>] | from-git]

'npm [-v | --version]' to print npm version
'npm view <pkg> version' to view a package's published version
'npm ls' to inspect current package/dependency versions

使用的规则也是遵循语义化版本号公约而设计,npm官方实践的细节可看 sermver.inc。

下面是关于版本选项的描述(假设默认版本为0.2.0):

选项 描述 例子 说明
major 重大更新版本 npm version major 0.2.0 =》1.0.0
minor 主要更新版本 npm version minor 0.2.0 =》0.3.0
patch 补丁更新版本 npm version patch 0.2.0 =》0.2.1
premajor 重大更新预发布版本 npm version premajor 0.2.0 =》1.0.0-0
preminor 主要更新预发布版本 npm version preminor 0.2.0 =》0.3.0-0
prepatch 补丁更新预发布版本 npm version prepatch 0.2.0 =》0.2.1-0
prerelease 预发布版本 npm version prerelease 当前版本不是预发布版本的会出错
from-git 拿取git的tag作为版本号设置至package.json内 npm version from-git git的tag标签没有设置的情况下,会抛出错误

关于prerelease的使用是存在前提。当前版本必须是预发布版本,如果不是预发布版本是会抛出错误的,使用时需要注意。使用[–preid]提供额外参数还可用于详细描述预发布版本的作用,比如需要实现下面这种情况:

1
2
3
# 更新为预发布版本号
$ npm version premajor --preid beta
v1.0.0-beta.0

使用from-git需要在当前git diff打上便签,且便签必须带上注释(annotated),不然会出错无法进行,如下面的情况:

1
2
3
4
5
6
$ npm version from-git --no-git-tag-version
npm ERR! code 128
npm ERR! Command failed: git -c core.longpaths=true describe --abbrev=0
npm ERR! fatal: No annotated tags can describe 'fe59b0da8f1ac0c61fb57d642190636ce9ed9659'.
npm ERR! However, there were unannotated tags: try --tags.
npm ERR!

问题解答引用至:《git fatal:No tags can describe

内容引用至:https://docs.npmjs.com/cli/v7/commands/npm-version

使用例子

场景1:简单使用

当前版本:0.2.0

行为:把版本更新至0.2.1,并在git中打上了v0.2.1的tag。

1
2
3
4
5
6
7
8
9
10
# 更新至新的补丁版本
$ npm version patch

# 打印git历史
$ git log
commit 39c8ba50f0ef18aab41ac9c65669b2769ed3b3a7 (HEAD -> master, tag: v0.2.1)
Author: Packy <lpreterite@126.com>
Date: Wed Apr 7 16:18:22 2021 +0800

0.2.1

场景2:自定义git的提交内容

当前版本:0.2.0

行为:更新版本号并进行git提交,自定义提交描述。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
$ npm version major -m "版本更新至%s"
v1.0.0

$ git log
commit 7b9e3102111f8f86fc70d1b1fcab96bb9389df9b (HEAD -> master, tag: v1.0.0)
Author: Packy <lpreterite@126.com>
Date: Wed Apr 7 17:01:36 2021 +0800

版本更新至1.0.0

commit eda4316722a9d03f2fd5e60f61507a6e272ddc1b
Author: Packy <lpreterite@126.com>
Date: Wed Apr 7 11:01:20 2021 +0800

chore: 更新package

场景3:不进行git操作

当前版本:0.2.0

行为:只更改package.json文件中version字段,并不会进行git操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 更新至新的补丁版本,并不增加git的tag
$ npm version patch --no-git-tag-version

$ git log
commit eda4316722a9d03f2fd5e60f61507a6e272ddc1b (HEAD -> master)
Author: Packy <lpreterite@126.com>
Date: Wed Apr 7 11:01:20 2021 +0800

chore: 更新package

$ git status
On branch master
Your branch is ahead of 'origin/master' by 6 commits.
(use "git push" to publish your local commits)

Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: package.json

no changes added to commit (use "git add" and/or "git commit -a")