npm的lock机制解析


Posted in Javascript onJune 20, 2019

npm是什么

npm是一个包管理工具,开源作者可以把开源包发布在平台上供其他人下载使用。前端的同学基本都使用过npm,这里就不做过多介绍。日常工作中npm的主要用途就是根据项目的package.json使用npm install去安装依赖。

npm install可以说是我们使用最频繁的一个指令。在npm5版本之前,npm install会根据package.json指定的依赖版本去进行安装。但往往package.json中指定的是一个版本范围,例如:

"dependencies": {
  "packageA": "^2.0.0"
},

以上这个 ^2.0.0 指定的范围是版本号大于等于2.0.0且大版本号为2。即2.6.10这个是符合的,而3.0.0和1.0.0这种是不符合的。
这样的范围指定会导致一个问题:A新建了一个项目,生成了上面这份package.json文件,但A安装依赖的时间比较早,此时packageA的最新版本是2.1.0,该版本与代码兼容,没有出现bug。后来B克隆了A的项目,在安装依赖时packageA的最新版本是2.2.0,那么根据语义npm会去安装2.2.0的版本,但2.2.0版本的API可能发生了改动,导致代码出现bug。

这就是package.json会带来的问题,同一份package.json在不同的时间和环境下安装会产生不同的结果。

理论上这个问题是不应该出现的,因为npm作为开源世界的一部分,也遵循一个发布原则:相同大版本号下的新版本应该兼容旧版本。即2.1.0升级到2.2.0时API不应该发生变化。

但很多开源库的开发者并没有严格遵守这个发布原则,导致了上面的这个问题。

lock机制

一个新的事物的诞生都是为了解决一个历史问题

基于这种状况,npm5推出了lock机制。在使用npm5.0.0之后的版本时,npm install后会自动生成package-lock.json文件,该文件记录了当前这次install所安装的依赖版本号。

例如当package.json的依赖如下:

"dependencies": {
  "vue": "^2.0.0"
 },

install后自动生成的package-lock.json会指定安装vue2.6.10版本(当前最新)

"dependencies": {
  "vue": {
   "version": "2.6.10",
   "resolved": "https://registry.npm.taobao.org/vue/download/vue-2.6.10.tgz",
   "integrity": "sha1-pysaQqTYKnIepDjRtr9V5mGVxjc="
  }
 }

package-lock.json相当于本次install的一个快照,它不仅记录了package.json指明的直接依赖的版本,也记录了间接依赖的版本。

如果我们想在不同环境和不同时间下每次install时安装相同版本的依赖,我们就可以把package-lock.json带上。

当package.json和package-lock.json同时存在时,npm install会去检测package-lock.json指定的依赖版本是否在package.json指定的范围内。如果在,则安装package-lock.json指定的版本。如果不在,则忽略package-lock.json,并且用安装的新版本号覆盖package-lock.json。

举个例子:

// package.json
"dependencies": {
  "vue": "^2.0.0"
 }

// package-lock.json
"dependencies": {
  "vue": {
   "version": "2.1.0",
   "resolved": "https://registry.npm.taobao.org/vue/download/vue-2.1.0.tgz",
   "integrity": "sha1-KTuj76rKhGqmvL+sRc+FJMxZfj0="
  }
 }

这种情况下package-lock.json指定的2.1.0在^2.0.0指定的范围内,npm install会安装vue2.1.0版本。

// package.json
"dependencies": {
  "vue": "^2.2.0"
 }

// package-lock.json
"dependencies": {
  "vue": {
   "version": "2.1.0",
   "resolved": "https://registry.npm.taobao.org/vue/download/vue-2.1.0.tgz",
   "integrity": "sha1-KTuj76rKhGqmvL+sRc+FJMxZfj0="
  }
 }

这种情况下package-lock.json指定的2.1.0不在^2.2.0指定的范围内,npm install会按照^2.2.0的规则去安装最新的2.6.10版本,并且将package-lock.json的版本更新为2.6.10。

值得注意的是npm5一发布时并不是采取这种install逻辑,在npm5.0到npm5.6之间install的逻辑发生了多次变更,而在npm5.6之后一直沿用当前这种逻辑。

npm ci

npm5之后的lock机制满足了要求锁版本的开发者们的需要,我们只需要拿到一份package-lock.json就可以知道要安装的依赖的具体版本号。但细心的同学会发现当package-lock.json指定的版本号不在package.json指定的范围内时,package-lock.json就会被更新覆盖。这可不利于我们去维持版本的固定。

因此后续npm也推出了npm ci的指令来解决这一问题,npm ci和npm i的不同之处在于:当package-lock.json指定的依赖版本不在package.json指定的依赖版本范围内时,npm会报错并取消安装。

npm的lock机制解析

这样我们就不怕在package-lock和package.json不一致时发生覆盖更新。

总结

在npm5.6以后我们就可以放心大胆地使用package-lock.json文件来锁版本,而在构建部署时可以使用npm ci安装命令来防止npm install的覆盖更新问题。

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

Javascript 相关文章推荐
利用JQuery为搜索栏增加tag提示
Jun 22 Javascript
JavaScript:Div层拖动效果实例代码
Aug 06 Javascript
javascript event在FF和IE的兼容传参心得(绝对好用)
Jul 10 Javascript
node.js中的path.extname方法使用说明
Dec 09 Javascript
jQuery实现仿Alipay支付宝首页全屏焦点图切换特效
May 04 Javascript
基于javascript实现页面加载loading效果
Sep 15 Javascript
jQuery动态添加可拖动元素完整实例(附demo源码下载)
Jun 21 Javascript
利用JavaScript实现拖拽改变元素大小
Dec 14 Javascript
基于Javascript倒计时效果
Dec 22 Javascript
Vue组件之自定义事件的功能图解
Feb 01 Javascript
微信小程序封装分享与分销功能过程解析
Aug 13 Javascript
如何正确解决VuePress本地访问出现资源报错404的问题
Dec 03 Vue.js
express如何解决ajax跨域访问session失效问题详解
Jun 20 #Javascript
JS去除字符串最后的逗号实例分析【四种方法】
Jun 20 #Javascript
如何在微信小程序中实现Mixins方案
Jun 20 #Javascript
js JSON.stringify()基础详解
Jun 19 #Javascript
使用jquery-easyui的布局layout写后台管理页面的代码详解
Jun 19 #jQuery
Vue-Cli 3.0 中配置高德地图的两种方式
Jun 19 #Javascript
vue axios重复点击取消上一次请求封装的方法
Jun 19 #Javascript
You might like
用cookies来跟踪识别用户
2006/10/09 PHP
php实现给二维数组中所有一维数组添加值的方法
2017/02/04 PHP
PHP基于正则批量替换Img中src内容实现获取缩略图的功能示例
2017/06/07 PHP
php封装单文件上传到数据库(路径)
2017/10/15 PHP
jQuery-Easyui 1.2 实现多层菜单效果的代码
2012/01/13 Javascript
DIV+CSS+JS不间断横向滚动实现代码
2013/03/19 Javascript
ECMAScript6的新特性箭头函数(Arrow Function)详细介绍
2014/06/07 Javascript
js动态添加onclick事件可传参数与不传参数
2014/07/29 Javascript
js实现防止被iframe的方法
2015/07/03 Javascript
javascript设计简单的秒表计时器
2020/09/05 Javascript
分享js粘帖屏幕截图到web页面插件screenshot-paste
2020/08/21 Javascript
在Vue中实现随hash改变响应菜单高亮
2020/03/09 Javascript
Python实现把utf-8格式的文件转换成gbk格式的文件
2015/01/22 Python
粗略分析Python中的内存泄漏
2015/04/23 Python
python中函数总结之装饰器闭包详解
2016/06/12 Python
Python爬取qq music中的音乐url及批量下载
2017/03/23 Python
pygame游戏之旅 添加游戏界面按键图形
2018/11/20 Python
让Python脚本暂停执行的几种方法(小结)
2019/07/11 Python
Python封装成可带参数的EXE安装包实例
2019/08/24 Python
python代码打印100-999之间的回文数示例
2019/11/24 Python
Python字典取键、值对的方法步骤
2020/09/30 Python
Python基于Socket实现简易多人聊天室的示例代码
2020/11/29 Python
CSS3等相关属性制作分页导航实现代码
2012/12/24 HTML / CSS
用纯css3实现的图片放大镜特效效果非常不错
2014/09/02 HTML / CSS
英国Radley包德国官网:Radley London德国
2019/11/18 全球购物
古驰英国官网:GUCCI英国
2020/03/07 全球购物
老师自我鉴定范文
2013/12/25 职场文书
文科毕业生自荐书范文
2014/04/17 职场文书
新农村建设典型材料
2014/05/31 职场文书
家庭贫困证明
2014/09/23 职场文书
家长对孩子的寄语
2015/02/26 职场文书
2015年学校办公室工作总结
2015/05/26 职场文书
事业单位工作人员岗前培训心得体会
2016/01/08 职场文书
2016大一新生入学教育心得体会
2016/01/23 职场文书
Python机器学习应用之工业蒸汽数据分析篇详解
2022/01/18 Python
解决IIS7下无法绑定https主机的问题
2022/04/29 Servers