详解package-lock.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或许会出现以下情况:
依赖A的下载的版本为: 1.最新版.最新版, 导致项目出现bug依赖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进行演示

^符号的意思: 版本号中最左边的非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.最新)
- 例如: package.json中包版本为
~符号的意思: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.最新)
- 例如: package.json中包版本为
*符号的意思: 直接下载这个包的最新版本- 例如: package.json中包版本为
*, 则下次会下载的版本为2.6.14 (vue2的最新版)
- 例如: package.json中包版本为
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 (最新.最新.最新)
- 例如: package.json中包版本为
精准版本号安装
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的生成、更新、使用时机
- 生成时机:
- 当项目有package.json文件并首次执行
npm install安装后, 会自动生成一个package-lock.json文件, 该文件里面记录了package.json依赖的模块,以及依赖的依赖。并且给每个依赖标明了版本, 获取地址和哈希值, 使得每次安装都会出现相同的结果, 不管你在什么机器上面或什么时候安装
- 当项目有package.json文件并首次执行
- 更新时机
- 使用命令重新安装特定版本的包
npm i less@3.12.0 - 在package.json中修改依赖版本后, 执行
npm install
- 使用命令重新安装特定版本的包
- 使用时机
- 执行
npm install时, 与package.json共同确定依赖包及依赖包的依赖的精确的版本号
- 执行
总结
- package.json用于告诉npm项目运行需要哪些包, 但包的最终安装的版本不能够只依靠这个文件进行识别, 还需以package-lock.json为准
- 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`的状态 - 为了保证该项目的环境依赖一致, 在项目移动时需要同时复制 package.json 和 package.lock.json 两个文件
- 不要轻易动package.json与package-lock.json
也许您最终还有疑问: 既然package.json会影响package-lock.json, 那后者lock的意义在哪?
我是这样理解的:
- package.json确定了项目依赖的版本, 但是没有lock住依赖的依赖的版本
- 而package-lock.json就是用来lock住项目依赖的依赖

全文到此结束, 希望对您有帮助~~~
详解package-lock.json的作用的更多相关文章
- package.json详解以及package-lock.json的作用
一.创建 package.json输入如下命令之后,会要求填写基本的配置信息,这里,我们选择一路回车即可,待生成 package.json 文件之后,再来配置. npm init 二.配置 packa ...
- 【转】详解spring 每个jar的作用
spring.jar 是包含有完整发布模块的单个jar 包.但是不包括mock.jar, aspects.jar, spring-portlet.jar, and spring-hibernate2. ...
- Java构造和解析Json数据的两种方法详解二——org.json
转自:http://www.cnblogs.com/lanxuezaipiao/archive/2013/05/24/3096437.html 在www.json.org上公布了很多JAVA下的jso ...
- [转] 详解http和https的作用与区别
PS: https就是http和TCP之间有一层SSL层,这一层的实际作用是防止钓鱼和加密.防止钓鱼通过网站的证书,网站必须有CA证书,证书类似于一个解密的签名.另外是加密,加密需要一个密钥交换算法, ...
- 详解http和https的作用与区别
PS: https就是http和TCP之间有一层SSL层,这一层的实际作用是防止钓鱼和加密.防止钓鱼通过网站的证书,网站必须有CA证书,证书类似于一个解密的签名.另外是加密,加密需要一个密钥交换算法, ...
- springMVC实现REST开发详解(补充Json解析问题以及静态文件404错误解决办法)
一.什么是REST? 符合REST约束风格和原则的应用程序或者设计就是REST 例如: /blog/1 HTTP GET =>查询id=1的blog /blog/1 HTTP DE ...
- json深度详解及org.json库
了解json (Javascript Object Notation) 网站:http://json.org/ english JSON (JavaScript Object Notation) i ...
- java 线程Thread.Sleep详解 Thread.Sleep(0)的作用(转载)
我们可能经常会用到 Thread.Sleep 函数来使线程挂起一段时间.那么你有没有正确的理解这个函数的用法呢? 思考下面这两个问题: 1.假设现在是 2008-4-7 12:00:00.000,如果 ...
- 详解spring 每个jar的作用
spring.jar 是包含有完整发布模块的单个jar 包.但是不包括mock.jar, aspects.jar, spring-portlet.jar, and spring-hibernate2. ...
- 转 -- 详解python的super()的作用和原理
原文地址 Python中对象方法的定义很怪异,第一个参数一般都命名为self(相当于其它语言的this),用于传递对象本身,而在调用的时候则不必显式传递,系统会自动传递. 今天我们介绍的主角是supe ...
随机推荐
- Spring系列之集成Druid连接池及监控配置
前言 前一篇文章我们熟悉了HikariCP连接池,也了解到它的性能很高,今天我们讲一下另一款比较受欢迎的连接池:Druid,这是阿里开源的一款数据库连接池,它官网上声称:为监控而生!他可以实现页面监控 ...
- 小程序 mpvue page "xxx" has not been registered yet
新增了几个页面,改了下目录结构,就开始报这个错. 重启了几次不管用,google 一番也无果. 灵机一动试一下 build npm run build build 版本没报错,OK 然后 $ rm - ...
- shp平滑处理
在做图像数据处理时,经常会有栅格数据转矢量数据的操作,转换后的矢量文件会存在锯齿状边缘,不太美观,因此常常需要对矢量(shp)文件做平滑处理. 1 利用arcgis实现shp的平滑和简化 ArcToo ...
- 浅析mybatis中${}和#{}取值区别
mybatis作为一个轻量级的ORM框架,应用广泛,其上手使用也比较简单:一个成熟的框架,必然有精巧的设计,值得学习. 在使用mybatis框架时,在sql语句中获取传入的参数有如下两种方式: ${p ...
- openswan框架和编译时说明
刚开始学习openswan项目代码时,自己尝试了在虚拟机上编译.安装.运行openswan代码,由于当时刚开始学习openswan代码,因此对于其构成并不清楚,在编译.运行过程中有了问题,基本是通过百 ...
- VUE带Token访问Abp Vnext Api
上篇登录保存token用了3种方式,都可以在header带上Token访问,本次使用第四种保存方式Vuex中保存状态 stroe中配置好需要保存的字段及方法 import Vue from 'vue' ...
- Input 只能输入数字,数字和字母等的正则表达式
JS只能输入数字,数字和字母等的正则表达式 1.文本框只能输入数字代码(小数点也不能输入) <input onkeyup="this.value=this.value.replace( ...
- 从线上日志统计接口访问量QPS
这一阵子在面试,连续遇到好几家(大小厂都有)问我的项目线上qps的情况了,说实话,我作为一个大头兵,本来没关注过这个数据,只能含混地给个"大概.也许"的回答. 回来之后,我决定对业 ...
- %v的使用
不同的类型,他们的默认的%v 一个变动的格式化字符串,相当于一个变量,遇到不同类型,就变形成不同的格式. 类型 %v bool %t int/int8/... %d uint/uint8/.. ...
- Spring Cloud Eureka 之常用配置解析
[原创内容,转载.引用请注明出处] 1. 配置项解析 1.1 通用配置 # 应用名称,将会显示在Eureka界面的应用名称列 spring.application.name=config-servic ...