政采云技术团队.png

刘静.png

> 这是第 159 篇不掺水的原创,想获取更多原创好文,请搜索公众号【政采云前端团队】关注我们吧~

前言

在日常工作中,当组件跨项目使用时,我们往往会选择把组件抽成 npm 包。那么在 npm 开发以及发布的过程中有什么需要注意的事项吗?本文将从我自己的角度,来为大家介绍一下我认为的一些需要大家注意的点。

版本号规则

从日常的开发中我们可以看到,npm 包的版本号的格式都是 X.Y.Z。那么大家发布的 npm 包为什么都在遵循这个格式呢?这个格式其实是由 Gravatars 创办者兼 GitHub 共同创办者 Tom Preston-Werneropen in new window 所建立。由 GitHub 起草的统一的版本号表示规则,称为 Semantic Versioning(语义化版本表示)。这些规范具体包含的内容大家可以参考语义化版本 2.0.0open in new window。本文只针对我们开发中容易忽略的地方做一些详述。

  • X 代表主版本号,也叫做大版本号

    升级大版本时意味着这个包可能做了颠覆性的改动,和低版本的包已经无法兼容。每当主版本号递增时,次版本号和修订号必须归零。

  • Y 代表次版本号,也叫做小版本号

    当做了向下兼容的功能性新增时,升级小版本号。每当次版本号递增时,修订号必须归零。

  • Z 代表修订号

    当做了向下兼容的问题修正(bugfix)时, 升级修订号。

常见版本格式/引用方式

<table> <tr> <td style="width: 130px">版本引用方式</td> <td style="width: 90px">版本号</td> <td>匹配版本</td> <td>解释</td> </tr> <tr> <td>直接使用版本号</td> <td>2.3.1</td> <td>2.3.1</td> <td>只可以匹配 2.3.1 这个版本,如果是比较重要的项目,建议用这种方式固定版本。</td> </tr> <tr> <td rowspan='3'>^:不能修改版本号最左侧非零数字</td> <td>^2.3.1</td> <td>>= 2.3.1 && < 3.0.0</td> <td>最左侧非零数字是 2</td> </tr> <tr> <td>^0.3.1</td> <td>>= 0.3.1 && < 0.4.0</td> <td>最左侧非零数字是 3</td> </tr> <tr> <td>^0.0.1</td> <td> >= 0.01 && < 0.02,即 0.01</td> <td>最左侧非零数字是 1</td> </tr> <tr> <td rowspan='2'>~:版本号列出 Y 时兼容 Z 的修改。列出 X 时兼容 Y、Z</td> <td>~2.3.1</td> <td>>= 2.3.1 && < 2.4.0</td> <td>Y 为 3。~2.3 同理</td> </tr> <tr> <td>~2</td> <td>>= 2.0.0 && < 3.0.0</td> <td>X 为 2</td> </tr> <tr> <td rowspan='3'>、X、x,空:表示可以匹配任何版本</td> <td>"2.3.X"、"2.3.x"、"2.3"、"2.3"</td> <td>>= 2.3.0 && < 2.4.0</td> <td>Z 可以为任意值</td> </tr> <tr> <td>"2.X"、"2.x"、"2."、"2"</td> <td>>= 2.0.0 && < 3.0.0</td> <td>Y、Z 为任意值</td> </tr> <tr> <td>、X、x,空</td> <td>任意版本</td> <td>任意版本指的是最新的正式版</td> </tr> </table>

关于 npm 的版本格式还有许多,此处不再赘述。

从上边的常用格式介绍可以看出来,在精确版本号的情况下,版本号是完全固定的,在项目发布时不会出现一些实际安装的包和 package.json 中版本号不一致的问题。或者如果使用方有用到 package-lock.json 文件来固定包的版本,也可以避免包的版本号导致的问题。

但是在实际开发中,我们并不知道我们包的使用方是否使用的固定版本号或者 package-lock.json 文件,我们怎么做才能让使用方不受影响呢?

这时候就要用到先行版本号了,下面我将为大家具体介绍。

先行版本

npm 的先行版本号,放到 X.Y.Z 的后边,作为延伸。被标上先行版本号则表示这个版本并非稳定而且可能无法满足预期的兼容性需求。例如:1.0.0-alpha.1,2.0.0-beta.1 等。一般常用的关键词有:

  • alpha:预览版,或者叫内部测试版;一般不向外部发布,会有很多bug(会不太稳定);一般只有测试人员使用。
  • beta:测试版,或者叫公开测试版;这个阶段的版本会一直加入新的功能;在alpha版之后推出。
  • rc(release candidate):最终测试版本;可能成为最终产品的候选版本,如果未出现问题则可发布成为正式版本。

先行版本升级规则

我们使用 npm dist-tag ls @zcy/zcy-region-detail-back 查看 @zcy/zcy-region-detail-back 的 tag,如下:

我们可以看到这个包有一个 beta 版,一个 latest 版。

对比两个版本的名字可以发现,beta 版本是在 latest 版本的 Z 上加了 1 且添加了一个 beta 作为延伸。

  • 如果包只是对现有的问题进行修复,那么只需要对 Z 进行加 1,然后添加延伸。
  • 如果包本次是做向下兼容的功能性新增,那么需要对 Y 进行加 1,Z 清零,然后添加延伸。
  • 如果包本次的升级是无法向下兼容的,那么就需要对 X 进行加 1,Y、Z 清零,然后添加延伸。

如果在加了延伸的版本上需要进行 bugfix 时,只需要将我们延伸的版本继续增加即可。当 bugfix 结束,需要发布正式版本时,只需要去掉延伸版本,发布版本即可。

什么时候需要使用先行版本

假设 P 项目中引用了 @zcy/zcy-region-detail-back 包,如下:

A 需求改动了项目 P,发布时间为 6.30。

B 需求改动了 @zcy/zcy-region-detail-back 包,改动的时间是 6.29。

B 需求的改动没有使用先行版本且包中的 bug 在 6.30 项目 P 发布时没有修改。此时就会导致项目 P 发布时,下载到了有 bug 的 @zcy/zcy-region-detail-back 包,就会导致线上问题。

这是因为我们在 P 项目中执行 npm i @zcy/zcy-region-detail-back 后,下载出来的 @zcy/zcy-region-detail-back 的版本号为 1.0.0。因为在执行 npm i @zcy/zcy-region-detail-back 时会默认下载 tag 为 latest 下的最新包。相当于执行了 npm i @zcy/zcy-region-detail-back@latest:这里的 tag 指的是 npm 中的 tag。

所以 npm 的 tag 到底有什么用呢?其实 tag 就相当于是 git 的分支管理中的标签,不同的 tag 之间的包互不影响。可以使我们发布先行版本时不影响正式版本。

一般常用的有三种类型的 tag:

  • latest:最后的稳定版,npm install 时就是下载的这个
  • beta:测试版本,需要指定版本或者使用 npm install packageName@beta 来下载。例如:1.0.0-beta.0
  • next:先行版本,使用 npm install packageName@next 安装

版本发布

那么我们如何发布先行版本的包呢?首先需要升级 A 包的版本号,此处介绍两种升级方式

方式一:简单粗暴,手动修改 package.json 中的 version:

image-20220313200823440

这种方式需要我们自己手动执行 git commit -am &#39;XXXX&#39; 提交代码,如果需要在此版本的 git 仓库打上 tag 时,需要我们自己手动触发git tag v2.3.2-beta.1git push origin v2.3.2-beta.1

方式二:借助 npm version 命令

A 包中所有的改动都 commit 后,可以根据以下命令更新版本

npm version [&lt;newversion&gt; | major | minor | patch | premajor | preminor | prepatch | prerelease | from-git]
// newversion:指定更新的版本号
// major:大版本并且不向下兼容时,使用 major
// minor:有新功能且向下兼容时,使用 minor
// patch:修复一些问题、优化等,使用 patch
// 以 A:2.3.1 为例
npm version premajor // 版本号会成为 3.0.0-0,即 3.0.0 的预发版本
npm version preminor // 版本号为成为 2.4.0-0,即 2.4.0 的预发版本
npm version prepatch // 版本号成为 2.3.2-0,即 2.3.2 的预发版本
/**
* 版本号会成为 2.3.2-0。
* 执行此命令时,如果没有预发布版本号,则增加 Z,增加预发布号为 0
* 如果有预发步号,增加预发步号
*/
npm version prerelease

根据上边的 API 可以看到我们能通过 npm version 2.3.2-beta.1 将 A 的版本升为 2.3.2-beta.1 的形式,除此之外,在 npm 6.4.0 之后,我们也可以使用 --preid 参数来添加前缀:

npm version prerelease --preid=beta

此种方式需要注意,必须要 commit 本地的修改之后才可以执行。npm version 修改版本号,会默认执行 git add -> git commit -> git tag 操作,此时的版本号看起来有 beta,如下:

image-20220703204725616

但是这个 beta 是 git 仓库的 tag,并不是 npm 的 tag。如果不想默认给 git 添加 tag 的话,可以使用以下命令:

npm --no-git-tag-version version xxx

那么 npm version 执行时具体发生了什么呢?简要流程图如下

执行完 npm version 2.3.2-beta.1 之后,如果直接使用 npm publish 来发布的话,发布出来的包的 tag 是 latest,但是我们其实是想发布一个测试包。如果其他人 npm i 下载时就会下载 version 为 2.3.2-beta.1 的包。只有使用 npm publish --tag XXX 才是给 npm 包上打了 tag 标签。

执行以下命令就可以生成一个 tag 为 beta 的包:

npm run build // 打包
npm publish --tag beta // 发布 beta 包

如果不小心直接使用 npm publish 发错了也没有关系,可以使用以下命令来添加 tag:

npm dist-tag add &lt;pkg&gt;@2.3.2-beta.1 &lt;tag&gt;

当需要删除多余的 tag 时:

npm dist-tag rm &lt;pkg&gt; &lt;tag&gt;

给大家提供一条指令完成 beta 版本的发布:

&quot;scripts&quot;: {
    &quot;publish:beta&quot;: npm version prerelease --preid=beta &amp;&amp; npm run build &amp;&amp; npm publish --tag=beta&quot;
  },

代码开发完毕,提交之后,只需要 npm run publish:beta 就可以发布一个测试版本啦~

以上就是我本次分享的所有内容啦,如果有不足的地方,还望指正。

参考文献

语义化版本 2.0.0open in new window

前端工程化(5):你所需要的npm知识储备都在这了open in new window

npm versionopen in new window

推荐阅读

你想知道的前后端协作规范都在这了open in new window

带你了解 Tree Shakingopen in new window

厉害!这篇正则表达式竟写的如此详尽open in new window

学习 HTTP Refereropen in new window

浅谈低代码平台远程组件加载方案open in new window

开源作品

  • 政采云前端小报

开源地址 www.zoo.team/openweekly/open in new window (小报官网首页有微信交流群)

  • 商品选择 sku 插件

开源地址 https://github.com/zcy-inc/skuPathFinder-back/open in new window

招贤纳士

政采云前端团队(ZooTeam),一个年轻富有激情和创造力的前端团队,隶属于政采云产品研发部,Base 在风景如画的杭州。团队现有 90 余个前端小伙伴,平均年龄 27 岁,近 4 成是全栈工程师,妥妥的青年风暴团。成员构成既有来自于阿里、网易的“老”兵,也有浙大、中科大、杭电等校的应届新人。团队在日常的业务对接之外,还在物料体系、工程平台、搭建平台、性能体验、云端应用、数据分析及可视化等方向进行技术探索和实战,推动并落地了一系列的内部技术产品,持续探索前端技术体系的新边界。

如果你想改变一直被事折腾,希望开始能折腾事;如果你想改变一直被告诫需要多些想法,却无从破局;如果你想改变你有能力去做成那个结果,却不需要你;如果你想改变你想做成的事需要一个团队去支撑,但没你带人的位置;如果你想改变既定的节奏,将会是“5 年工作时间 3 年工作经验”;如果你想改变本来悟性不错,但总是有那一层窗户纸的模糊… 如果你相信相信的力量,相信平凡人能成就非凡事,相信能遇到更好的自己。如果你希望参与到随着业务腾飞的过程,亲手推动一个有着深入的业务理解、完善的技术体系、技术创造价值、影响力外溢的前端团队的成长历程,我觉得我们该聊聊。任何时间,等着你写点什么,发给 ZooTeam@cai-inc.com