当前位置: 首页 > 后端技术 > Node.js

npm的锁机制解析

时间:2023-04-03 10:55:01 Node.js

npmnpm是什么?Npm是一个包管理工具。开源作者可以在平台上发布开源包,供他人下载使用。前端同学基本都用过npm,这里就不过多介绍了。npm在日常工作中的主要用途是根据项目的package.json使用npminstall安装依赖。npminstall可以说是使用频率最高的命令了。在npm5版本之前,npminstall会根据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不应更改。但是很多开源库的开发者并没有严格遵守这个发布原则,从而导致了上面的问题。锁机制一个新事物的诞生解决了一个历史问题基于这种情况,npm5推出了锁机制。当使用npm5.0.0之后的版本时,npminstall后会自动生成package-lock.json文件,记录本次安装的依赖的版本号。例如当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相当于此安装的快照。它不仅记录了package.json指示的直接依赖的版本,还记录了间接依赖的版本。如果我们希望在不同环境、不同时间每次安装时都安装相同版本的依赖,可以带上package-lock.json。当package.json和package-lock.json同时存在时,npminstall会检查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指定的范围内,npminstall会安装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="}}在这种情况下包-lock.json指定的2.1.0不在^2.2.0指定的范围内。npminstall会按照^2.2.0的规则安装最新版本2.6.10,同时更新package-lock.json的版本为2.6。10.值得注意的是,npm5发布时并没有采用这种安装逻辑。安装逻辑在npm5.0和npm5.6之间变化了很多次,npm5.6之后一直沿用现在的逻辑。npmcinpm5之后的锁机制满足了需要锁版本的开发者的需求。我们只需要获取一个package-lock.json就可以知道要安装的依赖的具体版本号了。但是细心的同学会发现,当package-lock.json指定的版本号不在package.json指定的范围内时,package-lock.json会被更新覆盖。这样不利于我们维护一个固定的版本。所以后续的npm也推出了npmci命令来解决这个问题。npmci和npmi的区别在于,当package-lock.json指定的依赖版本不在package.json指定的依赖版本范围内时,npm会报错并取消安装。这样,当package-lock和package.json不一致时,我们就不怕覆盖更新了。总结在npm5.6之后,我们可以放心大胆的使用package-lock.json文件来锁版本,并且可以使用npmci安装命令来防止构建部署时的npminstalloverwriteupdate问题。最后,我个人开了一个公众号“前端搬运工”,我会定期推送优秀的前端精选文章,拒绝入门无脑基础的文章,给大家带来不一样的前端视角。