likes
comments
collection
share

自动化发布npm包

作者站长头像
站长
· 阅读数 37

背景

还在老东家的时候,本人维护过一个内含超过80个npm包的前端组件库,超过5个团队需要在该代码库上维护开发代码。然鹅,林子大了,什么事情都会发生……

事件一:

某天,苦逼的打工仔——我,被分派了在原有的一个npm包上开发的需求。奇怪的是,这个包明明在线上有上报代码,可是在源码中死活找不到这份上报代码。

经过一番折腾,发现git上的master分支的npm包版本(v0.0.55)和远程npm库的npm包版本(v0.0.56)对不上。终于我意识到问题所在:一位同事在本地发布npm包后,没有把合并到master分支就跑路了……

自动化发布npm包

事件二:

隔壁的同事在修复该组件库中某个npm包的bug。本地调试死活没发现问题,线上的包却有问题。最后发现是另外一个同事修改了node_modules的代码编译后,本地发布npm包,这一操作完全跟踪不到。

自动化发布npm包

我想你已经发现问题所在,没错,导致这些问题的最终原因是 本地发布npm包。每一位开发者都有发布npm包到远程npm库的权限,导致一些开发者的“黑技术”完全跟踪不到,而且可以不按规范开发。 为了解决以上的问题,我将手动发包改为自动化发包。首先看看整个npm包的开发流程:

自动化发布npm包

可以看到,自动化版本升级主要包括两个流程——发布测试包和发布正式包。

自动化发布测试包

我们先聊聊如何自动化发布测试包。自动化发布过程需要借助CI/CD工具,如Github中名为Git Action的CI/CD工具,在我的老东家也有自己的CI/CD工具。这些CI/CD工具的共同特点是:可以通过git的钩子功能,触发对应脚本

自动化发布测试包主要用到的是git push的钩子。下面是整体流程:

自动化发布npm包

上图中的“构建并升级npm包”会有问题:组件库中有超过80个组件,如果构建并升级全部npm包,构建会很慢,而且浪费npm资源,所以我们需要增量构建升级,即只构建升级当前push中有变更的npm包。

增量构建升级

增量构建升级需要解决两个问题:

  • 找到增开发者量修改的npm包
  • 依赖构建升级:如果有其他npm包依赖修改的npm包,则这些依赖的npm包也要构建升级

上面两个问题只需要都可以使用一个monorepo工具来解决:NX.js

NX.js有执行器的概念:每一个npm包对应一个执行器,一个包也对应一个构建:

自动化发布npm包

拆分成更细粒度的执行器后,NX.js就可以选择性地构建部分npm包。

找到增量修改的npm包

NX是底层是通过 git diff + git merge-base 的方案来找到增量修改的npm包。

  • git diff: 找到两个commit之间有哪些文件不一样,
  • git merge-base:找到两条分支之间的共同祖先,比较方式如下:

自动化发布npm包

假设有两条分支:主分支master和功能分支feature。git merge-base 可以找到橙色共同祖先。与feature分支最新commit点4比较后,可以得出2、4 commit点的npm包变更列表。

得出待升级的npm包 & 发布

NX本身可以比较两个commit,找到增量修改的npm包,加上NX.js的npm包依赖分析能力,可以得出功能分支feature中待升级的npm包,命令如下:

nx print-affected --base=master --head=feature

该命令的作用是:通过git diff比较共同祖先commit与功能分支feature的最新commit,得出待升级的npm包列表。

然后遍历待升级的包列表,更新各个包的package.json。更新本包版本,并更新这些包包的dependencies的版本。再通过CI/CD的脚本升级这些包即可。

为了更好辨认npm包的来历,所有包的预发布版版本号标志都用同一个,格式如:1.0.0.feature-xx.202202100919,即分支加时间。

自动化发布npm包

自动化发布正式包

自动化发布正式包的流程如下:

自动化发布npm包

先来看第一步:本地生成版本号。开发者升级npm包,需要选择升级semver版本号中major、minor、patch的其中一个子版本号。为什么在选择在本地生成版本号,而不是在CI/CD上选择子版本号呢?因为CI/CD上的版本选择如果有误操作,不能重新操作,而且在流水线上选择也不方便。

再来看第二步。使用CI/CD中的merged的钩子,代码合并到master后才触发CI/CD中的 publish npm 包的脚本。这样可以保证master的npm包版本和实际npm包版本一致。

升级版本号工具

我们使用changesets工具让开发者在本地升级版本号。该工具能升级指定npm包的版本号和对应依赖npm包的版本号。而且还提供良好的交互式界面用于升级版本号:

自动化发布npm包

changsets工具还有一项特点:不会立即生成子版本号,而是生成changeset中间文件,最后消耗changeset文件的时候更改版本号。

自动化发布npm包

changsets的中间文件特性,可以解决合并到master时的版本冲突问题。先看看手动填写版本号的情况:

自动化发布npm包

如上图,如果在功能分支上手动填写版本号,代码合入时 master的npm版本有可能会更新,此时MR会有冲突。

使用changsets工具的话,功能分支生成的是changeset的中间文件,在MR后触发CI/CD工具的changeset publish脚本,消耗中间文件,并真正修改版本号和发版:

自动化发布npm包

changsets发布正式包流程

自动化发布npm包

上图是使用changsets工具后发布正式包的流程:先在本地生成changesets中间文件,代码合入成功后,如果有changesets中间文件,则只构建需要更新版本的npm包,消耗changesets文件并升级版本号,最后用git公共账号提交一个commit到master分支。

整体效果

通过自动化改造后,开发体验有显著的提升

  • 自动化省去的手动流程:申请包权限、理解包依赖、手动填写npm版本号和npm publish、手动解决版本号冲突。
  • 保证远程npm版本和master的npm版本一致
  • npm包权限收归到公共账号,不再有乱发包的问题
  • 自动化减少用户心智负担
转载自:https://juejin.cn/post/7242118772311900221
评论
请登录