NPM包管理中的陷阱

随着前端生态不断欣欣向荣的发展,NPM已成为了最大包管理分发平台。
但是问题也越来越多,比如一年前的left-pad事件,导致了大量的项目无法正常运行,正因为如此又出现了yarn,准备纠正一些问题。

最近接手了一个旧的项目,顺利的踩到了NPM中的一个坑,记录这次采坑经历,为今后时时敲响警钟。
项目中用到了dcodeIO/protobuf.js这个库解析数据,因为用到了json的描述文件,因此采用了light library方式进行使用。

以前这个项目一直很稳定的在使用者,但是我接手后运行,却无法进行正常的pb解析了,我想一定是我的“打开方式”有问题,尝试了N久无果,然后通过控制台的报错信息去定位具体的原因。

断点发现上面获取到的$protobuf对象,竟然是用到了minimal的库,又一遍遍的检查代码,也请教了之前开发的同事,验证了代码的使用上没有问题。

于是就将怀疑的目标转向到了protobuf.js这个库上了。
果然在GitHub上发现了蛛丝马迹。作者在2017年7月11号的时候修正了一个bug,如下
而之前版本是针对json-module,竟然依赖的是minimal的库,可见作者已经修复了这个问题,但是6月10日发布的6.8.0版本中顺利的带着这个bug发布了,可能是light方式使用的人不多,并没有被及时的发现并纠正。

我这是一个年初的项目,怎么会用到了最新release的6.8.0版本的依赖呢?

这个就得从NPM的包管理方式说起了。我们在package.json中的包依赖中经常能见到~^这两个标记,具体含义可以见这里二者的区别

一般开发阶段,我们安装包都是 npm i xxx -D这种方式,包管理往往会自动帮我们加上^这个标记,比如用到的protobuf.js的版本号是^6.7.3。那么意味着当官方发布6.8.0版本后,我再进行包安装的话,就会给我安装上6.8.0这个带bug的版本,从而引发了一系列不可预知的问题。要绕开上面我遇到的这个问题的话,我们则需要卸载6.8.0版本,然后在package.json中将6.7.3前面的^去掉,强制指定规定的版本。

理论上来说保持新版本依赖的使用可以帮忙修复原先的问题,但是也会引入新的bug,并不是意味着越新越好,在实际项目中还是追求稳定。因此可以在安装依赖的过程中强制指定版本或者试试新的yarn。