npm
中依赖版本号是 ^x.y.z
,能够包含哪些版本呢?前端
今天有同事遇到一个问题,咱们代码里依赖的某个npm
包,写的是版本是 hard-source-webpack-plugin@^0.12.0
,可是在执行 npm install
的时候,安装的始终是 0.12.0
这个版本,而不是这个包的最新版 0.13.1
。node
刚开始,我还觉得是由于有 lock
的缘由,好比有 package-lock.json
或者 yarn.lock
,我认识是某个lock文件里,锁定了版本为 0.12.0
。但实际状况是,因为以前同事的代码有点bug,虽然源码中的确是有package-lock.json
和 yarn.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
,感到有点奇怪,为何这些开源的包,不锁定依赖的第三方版本呢?
个人理解,大概是这两个方面:
nodejs
的 node_modules
是个比黑洞还深的坑,可见一般在咱们一个应用里,会依赖多少的第三方开源包。每个开源包,又会依赖不少别的包。若是每一个开源包都锁定本身的依赖版本,那么不少底层的基础包,可能会被安装不少个,虽然只是 patch
部分存在版本差别,那前端代码打包以后,体积无疑会增大不少。所以,开源包为了和其余的开源包 共享 更底层的包,就不能锁定本身的版本