详解package-lock.json的作用

更新日期: 2021-10-14阅读: 1.9k标签: json

详解package-lock.json

我们都知道package.json除了配置快捷的node script脚本, 最主要的作用还是: 用于记录下当前项目所应用到的依赖包, 但是既然都已经有了package.json文件了, 那么为什么项目中还需要一个package-lock.json呢? 本文就来为您详细分析!

package-lock.json的作用

作用: 锁定安装时的包的版本号及包的依赖的版本号, 以保证其他所有人人在使用 npm install 时下载的依赖包都是一致的

比如说:
我下载了A依赖的v1.0.0版本, 同时A依赖又是依赖与B依赖的v1.3.2版本和C依赖的v2.0.3版本开发的


那么对于package.json的话只会在dependencies 或者 devDependencies中记录类似下的内容:

{
    "dependencies": {
        "依赖A": "^1.0.0"
    }
}

那么下次安装依赖A或许会出现以下情况:

  1. 依赖A的下载的版本为: 1.最新版.最新版, 导致项目出现bug
  2. 依赖A所依赖的B依赖和C依赖下载了别的版本, 导致依赖A出现bug, 进而导致项目出现bug

packag.json只单纯记录本项目的依赖, 而没有记录下依赖的依赖, 并且依赖之间的版本号又没有明确固定, 导致无法保证依赖环境一致

而package-lock.json的出现就是解决上述问题, 它会详细的记录项目依赖的版本号及依赖的依赖的版本号, 如以下所示:

{
  "name": "test",
  "version": "1.0.0",
  "lockfileVersion": 2,
  "requires": true,
  "packages": {
    "": {
      "name": "test",
      "version": "1.0.0",
      "license": "ISC",
        "dependencies": {
            "依赖A": "^1.0.0"
        }
    },
    "node_modules/依赖A": {
        "dependencies": {
            "B依赖": "^1.3.2",
            "C依赖": "^2.0.3"
        }
    }
  }
}

版本号的定义规则与前缀对安装的影响

根据GNU中对版本号的定义规则:

中文版:
主版本号 . 子版本号 [ .修正版本号 [ .编译版本号 ] ]

英文版:
Major_Version_Number . Minor_Version_Number [ .Revision_Number [ .Build_Number ] ]

英文简化版:
Major . Minor . [ .Revision [.Build] ]


package.json中的前缀^符号 ~符号 *符号代表了对包安装版本的不同策略, 下面的示例都通过下载vue2进行演示

  1. ^符号的意思: 版本号中最左边的非0数字的右侧都用最新的版本数

    • 例如: package.json中包版本为^2.1.0, 则下次会下载的版本为2.6.14 (2.最新.最新)
    • 例如: package.json中包版本为^0.7.1, 则下次会下载的版本为0.7.6 (0.7.最新)
    • 例如: package.json中包版本为^0.6.0, 则下次会下载的版本为0.6.0 (0.6.最新)
  2. ~符号的意思: Major永远准确安装, Minor给出的则准确安装否则装最新, Revision永远装最新

    • 例如: package.json中包版本为~2.0.3, 则下次会下载的版本为2.0.8 (2.0.最新)
    • 例如: package.json中包版本为~0, 则下次会下载的版本为0.12.16 (0.最新.最新)
    • 例如: package.json中包版本为~3.1, 则下次会下载的版本为3.1.5 (3.1.最新)
  3. *符号的意思: 直接下载这个包的最新版本

    • 例如: package.json中包版本为*, 则下次会下载的版本为2.6.14 (vue2的最新版)
  4. x符号的意思: x占位开始, 全部使用最新

    • 例如: package.json中包版本为"2.3.x", 则下次会下载的版本为2.3.4 (2.3.最新)
    • 例如: package.json中包版本为"2.x.x", 则下次会下载的版本为2.6.14 (2.最新.最新)
    • 例如: package.json中包版本为"x.x.x", 则下次会下载的版本为2.6.14 (最新.最新.最新)
    • 例如: package.json中包版本为"x", 则下次会下载的版本为2.6.14 (最新.最新.最新)
  5. 精准版本号安装

    npm i vue@2.6.14 # 下载Vue的2.6.14版本

改动package.json后依旧能改变项目依赖的版本

网上有很多博文说在npm版本5之后, 不能直接修改package.json中依赖包的版本来改变项目的安装, 因为项目版本已经被锁定在package-lock.json, 因此只能通过npm i 依赖@版本号的方法来改变版本

但是据我实际操作, 在npm版本为(v7.24.0), 直接修改package.json中依赖包的版本可以改变项目的安装, 并且会更新到package-lock.json中


当前项目的真实版本号应该以package-lock.json为标准

示例:
我本地的项目1的package.json

{
  "name": "project1",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "less": "^3.8.0"
  }
}

张三想在他那运行我的项目, 为此他只将package.json复制到他的机器上然后运行npm i命令安装项目运行所需的环境依赖

会出现以下情况: package.json中less编译器的版本并没变(还是 ^3.8.0), 但是less编译器的实际版本却是3.13.1, 即3大版本中的最新版, 再看自动生成的package.lock.json就会发现版本为3.13.1, 与实际版本相同, 所以package-lock.json中的依赖版本才是最为真实的, 不能盲目相信package.json

张三 npm i 后项目1的package.json

{
    "name": "project1",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
      "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
      "less": "^3.8.0"
  }
}

张三npm i后项目1的package.lock.json

{
    "less": {
      "version": "3.13.1"   // 这才是真实版本号
    }
}

package.lock.json的生成、更新、使用时机

  1. 生成时机:
    • 当项目有package.json文件并首次执行npm install安装后, 会自动生成一个package-lock.json文件, 该文件里面记录了package.json依赖的模块,以及依赖的依赖。并且给每个依赖标明了版本, 获取地址和哈希值, 使得每次安装都会出现相同的结果, 不管你在什么机器上面或什么时候安装
  2. 更新时机
    • 使用命令重新安装特定版本的包npm i less@3.12.0
    • 在package.json中修改依赖版本后, 执行npm install
  3. 使用时机
    • 执行npm install时, 与package.json共同确定依赖包及依赖包的依赖的精确的版本号

总结

  1. package.json用于告诉npm项目运行需要哪些包, 但包的最终安装的版本不能够只依靠这个文件进行识别, 还需以package-lock.json为准
  2. package.json中修改版本号会影响package-lock.json, 并且package.json比package.lock.json的优先级高, 如果package.json中less版本为^1.0.0 , package-lock.json中less版本为2.1.2, 则最终安装的less版本为1.7.5, package-lock.json中less即其依赖的包将被从2.1.2退回到1.7.5`的状态
  3. 为了保证该项目的环境依赖一致, 在项目移动时需要同时复制 package.json 和 package.lock.json 两个文件
  4. 不要轻易动package.json与package-lock.json

也许您最终还有疑问: 既然package.json会影响package-lock.json, 那后者lock的意义在哪?

我是这样理解的:

  1. package.json确定了项目依赖的版本, 但是没有lock住依赖的依赖的版本
  2. 而package-lock.json就是用来lock住项目依赖的依赖



全文到此结束, 希望对您有帮助~~~

原文来自:https://www.cnblogs.com/fitzlovecode/archive/2021/10/13/diff_between_package_and_package-lock.html


链接: https://fly63.com/article/detial/10732

web数据格式中关于:XML/HTML/JSON学习总汇

这篇文章讲解关于XML/HTML/JSON的学习,大家都知道服务器端可以返回的数据格式,主要就是:XML、HTML、JSON,当我们做数据抓取,ajax请求的时候都需要熟悉它们的使用。

解决IE8下JSON.stringify()自动将中文转译成unicode的方法

在IE8下JSON.stringify()自动将中文转译为unicode编码,原本选择的中文字符,传到后台变为了unicode编码,即u****的形式。查找资料后发现,与标准的JSON.stringify()不同,IE8内置的JSON.stringify()会自动将编码从utf-8转为unicode编码,导致出现这种类似于乱码的情况。

js实现json格式化,以及json校验工具的简单实现

这篇文章主要讲解:json结构及形式、json字符串转化为json对象【通过eval( ) 方法,new Function形式,使用全局的JSON对象】、json校验格式化工具简单实现

解析Json字符串的三种方法

在很多时候,我们的需要将类似 json 格式的字符串数据转为json,下面将介绍日常中使用的三种解析json字符串的方法

解决IE8以下低版本实现JSON.parse()与JSON.stringify()的兼容

将字符串和json对象的相互转换,我们通常使用JSON.parse()与JSON.stringify()。解决IE8以下低版本实现JSON.parse()与JSON.stringify()的兼容呢:利用eval方式解析、new Function形式、自定义兼容json的方法、head头添加mate等

什么是数据交互格式?xml和json优缺点

就是客户端和服务端进行信息传输的格式(xml和json),双方约定用什么格式进行传输,然后解析得到自己想要的值,xml扩展标记语言,属于重量级(第一占宽带、第二解析难),json属于轻量级的数据交互格式(不占宽带,解析很简单)

js 将json字符串转换为json对象的方法解析

将json字符串转换为json对象的方法。在数据传输过程中,json是以文本,即字符串的形式传递的,而JS操作的是JSON对象,所以,JSON对象和JSON字符串之间的相互转换是关键

聊聊JSON Schema

json现在已经成为比较通用灵活的数据交换格式,尤其是在web方面,总是少不了它的身影,js原生就支持它。网页中与服务器中和服务器交换信息也基本上式基于json的。在现在的开发中,特别是在前后端分离的开发中,后端提供接口,前端通过接口拿取数据;

百度JSON LD结构化数据代码分享

百度JSON LD结构化数据代码分享,搞外贸网站,企业网站这么就,对谷歌的 schema 结构化数据比较熟悉,但是对百度的结构化数据就了解太少了

什么是JWT(JSON WEB TOKEN)

Json web token(JWT)是为了网络应用环境间传递声明而执行的一种基于JSON的开发标准(RFC 7519),该token被设计为紧凑且安全的,特别适用于分布式站点的单点登陆(SSO)场景。JWT的声明一般被用来在身份提供者和服务提供者间传递被认证的用户身份信息

点击更多...

内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!