Node.js中package.json中库的版本号(~和^)

所属分类: 网络编程 / JavaScript 阅读数: 549
收藏 0 赞 0 分享

~和^的区别

最近总是碰到一些问题, 在本地好好的, 在线上就出现了问题, 本地也一直复现不了, 后来把node_modules目录删除了之后, 重新安装, 就在本地复现了这个问题,可以看了git history, 并没有人修改package.json中的版本号,于是认真的了解了一下package.json中库的版本号;

~和^的区别

"babel-loader": "^7.1.1",
"body-parser": "~1.15.2"

npm install --save xxx, 会优先考虑使用 ^而不是~

以版本号x.y.z为例

x:主版本号, 当你做了不兼容的API修改

y:次版本号, 当你做了向下兼容的功能性问题

z:修订号, 当你做了向下兼容的问题修复

~x.y.z, 会更新到y最新的版本, 例如 body-parser: ~1.15.2, 这个库会去匹配到1.15.z的最新版本, 如果出现了1.16.0, 则不会自动升级
^x.y.z, 会更新到x的最新版本, 例如 babel-loader: ^7.1.1, 这个库会去匹配7.y.z的最新版本, 如果出现了8.1.1, 则不会自动升级

'~'(波浪符号):他会更新到当前minor version(也就是中间的那位数字)中最新的版本。放到我们的例子中就是:"exif-js": "~2.3.0",这个库会去匹配更新到2.3.x的最新版本,如果出了一个新的版本为2.4.0,则不会自动升级。波浪符号是曾经npm安装时候的默认符号,现在已经变为了插入符号。
'^'(插入符号): 这个符号就显得非常的灵活了,他将会把当前库的版本更新到当前major version(也就是第一位数字)中最新的版本。放到我们的例子中就是:"vue": "^2.2.2", 这个库会去匹配2.x.x中最新的版本,但是他不会自动更新到3.0.0。

可以参考npm官方给出的解释

^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是开源的世界, 并不是所有的都严格遵循这种规则, 所以会出现上述的问题;

为什么需要package锁

有如下几个可能原因, 在某些情况下, package.json是无法保证每个人自己电脑上执行的 npm install 后安装的依赖版本都是一样的

1.如果package.json中记录的依赖包的版本是一个版本范围, 一旦执行npm i 会导致这个包更新到最新版本

2.就算你依赖了一个固定版本的包(如A 1.1.1), 但你依赖的包A可能依赖其他的包B,而A在声明依赖时可能也使用了semser命名, 如 ^1.2.3, 如果包B release 了新版, 也会导致包B会安装到更新版本

3.不同人使用的npm程序的版本不同

如果依赖包的版本不一致, 会导致开发环境和生产环境产品不一致的行为; 或者导致不同团队成员之前也产品环境差异

如何解决包版本不一致的情况

1.npm 使用package-lock.json文件来解决这个问题

执行npm install会自动生成package.json文件, 只要执行普通的安装, 更新等可能会修改 package.json的npm命令, 都会自动同步修改package-lock.json文件

npm install xxx
npm rm xxx
npm update xxx

2.npm 还支持npm-shrinkwrap.json, 和package-lock.json功能完全一样

执行 npm shrinkwrap来生成npm-shrinkwrap.json

此命令将根据 package-lock.json 文件创建一个新的或覆盖已有的 npm-shrinkwrap.json 文件。 此命令创建和更新的文件将优先于任何其他现有或将有的 package-lock.json 文件。

3.使用yarn

使用yarn主要有一下优点

  • 快速: 会缓存它下载的每个包,无需重复下载;能并行化操作以最大资源利用率
  • 可靠:使用格式详尽而又简洁的 lockfile文件 和确定性算法来安装依赖,能够保证在一个系统上的运行的安装过程也会以同样的方式运行在其他系统上。
  • 安全: 安装包被执行前校验其完整性
  • yarn速度比npm快一些, yarn的锁文件是yarn.lock, 能解决包版本不一致的情况

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

更多精彩内容其他人还在看

jQuery LigerUI 使用教程表格篇(1)

ligerGrid是ligerui系列插件的核心控件,用户可以快速地创建一个美观,而且功能强大的表格,支持排序、分页、多表头、固定列等等
收藏 0 赞 0 分享

JavaScript中常用的运算符小结

JavaScript中常用的运算符小结,需要的朋友可以参考下。
收藏 0 赞 0 分享

深入理解JavaScript系列(13) This? Yes,this!

在这篇文章里,我们将讨论跟执行上下文直接相关的更多细节。讨论的主题就是this关键字。实践证明,这个主题很难,在不同执行上下文中this的确定经常会发生问题
收藏 0 赞 0 分享

javascript (用setTimeout而非setInterval)

javascript (用setTimeout而非setInterval)如果用setInterval 可能出现 下次调用会在前一次调用前调用
收藏 0 赞 0 分享

JavaScript中两个感叹号的作用说明

用两个感叹号的作用就在于,如果明确设置了o中flag的值(非null/undefined/0""/等值),自然test就会取跟o.flag一样的值;如果没有设置,test就会默认为false,而不是null或undefined
收藏 0 赞 0 分享

javascript写的简单的计算器,内容很多,方法实用,推荐

最近用javascript写了一个简单的计算器,自己测试感觉还好,代码都给了注释,非常不错,推荐大家学习。
收藏 0 赞 0 分享

js的表单操作 简单计算器

javascript写的简单的加减乘除计算器,里面涉及到一些方法还是很实用的哦,新手不要错过
收藏 0 赞 0 分享

Jquery中删除元素的实现代码

empty用来删除指定元素的子元素,remove用来删除元素,或者设定细化条件执行删除
收藏 0 赞 0 分享

javaScript 利用闭包模拟对象的私有属性

JavaScript缺少块级作用域,没有private修饰符,但它具有函数作用域。作用域的好处是内部函数可以访问它们的外部函数的参数和变量(除了this和argument
收藏 0 赞 0 分享

为JavaScript类型增加方法的实现代码(增加功能)

大家在js开发过程中有些功能已经满足不了我们的需求,或没有我们需要的功能,那么我们就可以自己扩展下,个性化js
收藏 0 赞 0 分享
查看更多