package-lock.json的作用是什么?


288

npm @ 5已发布,它具有一个新功能package-lock.json文件(位于之后npm install),这使我感到困惑。我想知道此文件的作用是什么?

Answers:


287

它存储精确的版本化的依赖关系树,而不是使用加星标的版本控制(如package.json本身(例如1.0。*))。这意味着您可以保证对其他开发人员或产品发行版等的依赖性。它还具有锁定树的机制,但通常会在package.json更改时重新生成。

npm docs中

对于npm修改node_modules树或package.json的任何操作,都会自动生成package-lock.json。它描述了生成的确切树,因此无论中间依赖项更新如何,后续安装都可以生成相同的树。

该文件旨在提交到源存储库中,并具有多种用途:

描述依赖关系树的单个表示形式,这样可以确保队友,部署和持续集成安装完全相同的依赖关系。

为用户提供一种便利,使其可以“时间旅行”到node_modules的先前状态,而不必提交目录本身。

为了通过可读的源代码控制差异更好地了解树的变化。

并允许npm跳过以前安装的软件包的重复元数据解析,从而优化安装过程。”

编辑

要回答jrahhali的以下问题,即仅使用具有确切版本号的package.json。请记住,您的package.json仅包含直接依赖项,而不包含依赖项的依赖项(有时称为嵌套依赖项)。这意味着,使用标准package.json,您将无法控制这些嵌套依赖项的版本,直接引用它们或将其作为对等依赖项将无济于事,因为您还无法控制直接依赖项为这些嵌套依赖项定义的版本容忍度。

即使锁定直接依赖项的版本,您也不能100%保证每次的完全依赖关系树都相同。其次,您可能希望允许对直接依赖项进行不间断的更改(基于语义版本控制),这使您对嵌套依赖项的控制甚至更少,并且再次不能保证直接依赖项在某些时候不会破坏语义版本控制规则他们自己。

所有这些的解决方案是锁定文件,如上所述,锁定文件锁定完整依赖关系树的版本。这使您可以为其他开发人员或发行版保证依赖关系树,同时仍允许使用标准package.json测试新的依赖关系版本(直接或间接)。

注意 先前的收缩包装json几乎做了同样的事情,但是锁文件将其重命名,以便其功能更加清晰。如果项目中已经有收缩包装文件,则将使用它来代替任何锁定文件。


78
如果要寻求具有确切版本的依赖关系,为什么不强制在package.json中指定确切版本并放弃package-lock.json文件?
jrahhali

15
@jrahhali-根据您的问题修改了我的答案。
马特

1
pacakge.json.lock的依赖树如何应用于其他开发人员?自动吗?
2010年

40
请注意,此答案不再正确!从NPM 5.1开始,每次调用npm install时package-lock.json文件都会更新一次。(更改github.com/npm/npm/issues/16866,例如github.com/npm/npm/issues/17979)因此,除非您指定确切的版本,否则它不能再用于为所有开发人员设置相同的版本。1.2.3,而不是1.2.*在你的package.json文件中。
基督教徒

5
您应该添加一个对的引用,npm cinpm install更新package-lock.json,而ci使用其内容。只有这样,npm ci您才能获得可重复的强大构建。
k0pernikus

34

对于npm来说,这是一个非常重要的改进:确保每个软件包的版本完全相同

如何确保您的项目在不同的时间,不同的环境中使用相同的软件包构建?假设您可以^1.2.3在中使用package.json,或者您的某些依赖项正在使用这种方式,但是您如何确保每次npm install都能在开发机和构建服务器中使用相同的版本?package-lock.json将确保这一点。

npm install在构建服务器或部署服务器上时,将重新生成锁定文件npm ci(将从锁定文件中读取并安装整个程序包树)


9
请注意,这有点过时了。从5.1.0开始,“ npm install”根本不会从package-lock.json文件中读取。它只是package.json像以前那样安装。要使用该package-lock.json文件,您必须使用新的“ npm ci”命令,该命令将安装中列出的确切版本,package-lock.json而不是中给出的版本范围package.json
Venryx

5
恐怕Venryx是不正确的。 npm install 确实从读取package-lock.json。若要进行复制,请执行以下操作。使用此的package.json,运行npm install{... “devDependencies”:{ “兴农”: “7.2.2”}}现在,复制/粘贴package.json,并package-lock.json到一个新的目录。更改package.json为:“ sinon”:“ ^ 7.2.2” run npm install。npm从package-lock.json中读取并安装7.2.2而不是7.3.0。如果没有package-lock.json,将安装7.3.0。
zumafra

2
不仅如此,而且如果您想做类似添加插入符^的操作package-lock.json,唯一可行的方法是使用删除package-lock.json并重新生成它npm install。(您不想手动编辑package-lock.json)。更改的“版本”属性的值(在顶部附近)package.json将更改package-lock.jsonon npm install,但是将插入符添加到依赖项将不会对相同package-lock.json
zumafra

1
可以将其package.json视为可以手动修改的package-lock.json东西,而不必将其手动触摸。您始终对两个文件都进行版本控制-特别是package-lock.json。打开两个文件,在中手动编辑项目名称package.json,运行npm install并观察中的项目名称更改package-lock.jsonlicense似乎没有记录在中package-lock.json
zumafra

2
@zumafra包lock.json文件将被使用在做的时候npm cinpm install只需要使用的package.json,即使锁定文件提供

13

package-lock.json当在中更改属性(例如“ version”属性或依赖项属性)中的数值时,写入package.json

如果这些数值在package.jsonpackage-lock.json匹配,package-lock.json则从中读取。

如果这些数值中的package.jsonpackage-lock.json不匹配,package-lock.json则使用这些新值和新修饰符(如插入符号和代字号)(如果存在)写入。但这是触发更改为的数字package-lock.json

要了解我的意思,请执行以下操作。使用package.json不带package-lock.json,运行npm install带:

{
  "name": "test",
  "version": "1.0.0",
  ...
  "devDependencies": {
    "sinon": "7.2.2"
  }
}

package-lock.json 现在将具有:

"sinon": {
  "version": "7.2.2",

现在将两个文件复制/粘贴到新目录。更改package.json为(仅添加插入号):

{
  "name": "test",
  "version": "1.0.0",
  ...
  "devDependencies": {
    "sinon": "^7.2.2"
  }
}

运行npm install。如果没有package-lock.json文件,将安装sinon@7.3.0。npm install正在读取 package-lock.json并安装7.2.2。

现在更改package.json为:

{
  "name": "test",
  "version": "1.0.0",
  ...
  "devDependencies": {
    "sinon": "^7.3.0"
  }
}

运行npm installpackage-lock.json写入,现在将显示:

"sinon": {
  "version": "^7.3.0",

7

还要提及的一件事是软件包锁定文件附带的安全性改进。如果有人篡改公共npm注册表并更改软件包的源代码,甚至不更改软件包本身的版本,由于它保留了软件包的所有哈希值,因此它将被软件包锁定文件检测到。


4

对于npm修改node_modules树或package.json的任何操作,都会自动生成package-lock.json。它描述了生成的确切树,因此无论中间依赖项更新如何,后续安装都可以生成相同的树。

它描述了一个依赖关系树的单一表示形式,因此可以确保队友,部署和持续集成安装完全相同的依赖关系。它包含以下属性。

    {
"name": "mobileapp",
"version": "1.0.0",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
"@angular-devkit/architect": {
  "version": "0.11.4",
  "resolved": "https://registry.npmjs.org/@angular- devkit/architect/-/architect-0.11.4.tgz",
  "integrity": "sha512-2zi6S9tPlk52vyqNFg==",
  "dev": true,
  "requires": {
    "@angular-devkit/core": "7.1.4",
    "rxjs": "6.3.3"
  }
},

}


2

该文件由npm自动创建并使用,以跟踪软件包安装并更好地管理项目依赖项的状态和历史记录。您不应该更改此文件的内容。


1
那么如果我与此文件发生冲突怎么办?
奥利弗·沃特金斯

0

package-lock.json:它包含当前为您的应用程序安装的确切版本详细信息。


1
嗨,欢迎光临 这个问题已经回答。您必须验证问题是否已标记为已回答,看看是否有任何答案在前面都有绿色的提示。
内斯托尔
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.