npm install 版本号^的坑

npm中依赖版本号是 ^x.y.z,能够包含哪些版本呢?前端

今天有同事遇到一个问题,咱们代码里依赖的某个npm包,写的是版本是 hard-source-webpack-plugin@^0.12.0,可是在执行 npm install 的时候,安装的始终是 0.12.0这个版本,而不是这个包的最新版 0.13.1node

刚开始,我还觉得是由于有 lock的缘由,好比有 package-lock.json 或者 yarn.lock,我认识是某个lock文件里,锁定了版本为 0.12.0。但实际状况是,因为以前同事的代码有点bug,虽然源码中的确是有package-lock.jsonyarn.lock文件的,可是实际发版的时候,因为代码的bug,并无将这两个文件发布到npm仓库里。webpack

目前的状况就是,package.json里写的版本是 ^0.12.0,这个包在 npm源的最新版是 0.13.1。可是经过npm安装出来,始终是0.12.0的,并非0.13.1。web

根据以前的理解,语义的版本是 ^0.12.0,那么是能够覆盖到 [major, minor, patch] 三位版本中的 后两位 的,按理说应该会自动安装 0.13.1 这个版本啊。shell

难道是缓存的锅?嗯,有可能,npm的确是在本地有缓存的啊。因而清除掉本地的缓存 npm cache clean —force,再从新安装,WFT?仍是 0.12.0 啊!!npm

看来不是缓存的锅。那是网络问题么?也不是,清除掉缓存都仍是能安装到 0.12.0 ,网络确定是OK的……json

貌似,客观缘由 都排查得差很少了……只能从 主观方面 找问题了。缓存

版本号 ^0.12.0 ,真的包含了 0.13.1 么??网络

再翻出 npm版本官方文档 看看,嗯,以前的确理解错了。文档里明确说了,^指明的版本范围,只要修改 [major, minor, patch] 三元组中,最左侧的第一个非0位,都是能够的。也就是说,要肯定 ^版本包含的范围,先要找到 最左侧的第一个非0位 ,只有在这一位右侧的变更,才被包含在这个 ^ 指定的范围内。举个🌰:工具

  • ^1.2.3版本包括:>= 1.2.3 而且 < 2.0.0
  • ^0.2.3版本包括:>= 0.2.3 而且 < 0.3.0
  • ^0.0.3版本包括:>= 0.0.3 而且 < 0.0.4

同时,在官网还找到一个 npm命令行工具:semver,能够安装到全局:npm i -g semver ,以后,能够用这个工具来检查某个范围版本具体包含哪些,拿今天遇到的问题,就能够这样:

bogon:~ jess$ semver -r ^0.12.0 0.12.0 0.13.0 0.13.1
0.12.0
bogon:~ jess$
bogon:~ jess$ semver -r ^0.12.0 0.12.0 0.12.1 0.12.10 0.13.0 0.13.1
0.12.0
0.12.1
0.12.10
bogon:~ jess$
bogon:~ jess$
复制代码

PS

咱们目前在应用的代码里,为了防止某些包在升级过程当中,没有遵循语义化版本,致使咱们应用在每次打包后,生成的代码可能不一样,通常都会用 yarn.lock 或者 package-lock.json 来锁定项目依赖的包的版本号。

可是上次有同窗在开源的 第三方包 里,发现大多数都没有 yarn.lock 或者 package-lock.json,感到有点奇怪,为何这些开源的包,不锁定依赖的第三方版本呢?

个人理解,大概是这两个方面:

  1. 都说nodejsnode_modules是个比黑洞还深的坑,可见一般在咱们一个应用里,会依赖多少的第三方开源包。每个开源包,又会依赖不少别的包。若是每一个开源包都锁定本身的依赖版本,那么不少底层的基础包,可能会被安装不少个,虽然只是 patch 部分存在版本差别,那前端代码打包以后,体积无疑会增大不少。所以,开源包为了和其余的开源包 共享 更底层的包,就不能锁定本身的版本
  2. 其实第一点已经说明了问题,做为开源包的做者,可能也没有其余选择了,只能选择相信 其余的开源包做者,都会严格遵照 语义化版本 的要求

相关文档

相关文章
相关标签/搜索