"package-lock.json"角色

Sec*_*tle 217 npm

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

Mat*_*att 207

它存储一个精确的版本化依赖树,而不是使用像package.json本身那样的星号版本(例如1.0.*).这意味着您可以保证其他开发人员或prod版本等的依赖关系.它还有一种锁定树的机制,但如果package.json发生更改,通常会重新生成.

npm github页面:

对于npm修改node_modules树或package.json的任何操作,都会自动生成package-lock.json.它描述了生成的确切树,以便后续安装能够生成相同的树,而不管中间依赖性更新.

此文件旨在提交到源存储库,并用于各种目的:

描述依赖关系树的单个表示,以确保队友,部署和持续集成能够安装完全相同的依赖关系.

为用户提供一种"时间旅行"到node_modules的先前状态的工具,而无需提交目录本身.

通过可读的源代码控制差异来促进树更改的更大可见性.

并通过允许npm跳过以前安装的软件包的重复元数据解析来优化安装过程."

编辑

回答jrahhali的问题,关于将package.json与精确版本号一起使用.请记住,package.json仅包含直接依赖项,而不包含依赖项的依赖项(有时称为嵌套依赖项).这意味着使用标准的package.json,您无法控制这些嵌套依赖项的版本,直接引用它们或因为对等依赖项无法帮助,因为您也无法控制直接依赖项为这些嵌套依赖项定义的版本容差.

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

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

NB.之前的收缩包装json做了几乎相同的事情,但锁定文件重命名它,以便它的功能更清晰.如果项目中已经有一个收缩包装文件,那么将使用它来代替任何锁定文件.

  • 如果要求具有确切版本的依赖项,为什么不强制指定package.json中的确切版本并放弃package-lock.json文件? (67认同)
  • 请注意,这个答案**不再正确**!自NPM 5.1以来,每次调用npm install**时都会更新`package-lock.json`文件.(更改为https://github.com/npm/npm/issues/16866,示例在https://github.com/npm/npm/issues/17979)因此可以**不再用于设置相同所有开发人员的版本**,除非你在`package.json`文件中指定了`1.2.3`而不是`1.2.*`的确切版本. (31认同)
  • 您应该添加对“npm ci”的引用,因为“npm install”将更新 package-lock.json,而 ci 使用其内容。只有使用“npm ci”,您才能获得可重复的健壮构建。 (14认同)
  • @jrahhali - 根据你的问题修改了我的答案. (12认同)
  • 如何从 pacakge.json.lock 获取此依赖树应用于其他开发人员?自动地? (3认同)
  • 但是如果你的所有依赖项和依赖项的依赖项等也在它们自己的 package.json 中使用确切的版本,那么就不需要它了?即大多数软件包不使用确切的版本吗? (2认同)

Xin*_*Xin 20

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

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

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

  • 请注意,这有点过时了。从5.1.0开始,“ npm install”根本不会从package-lock.json文件中读取。它只是像以前那样从package.json安装。要使用“ package-lock.json”文件,您必须使用新的“ npm ci”命令,该命令将安装“ package-lock.json”中列出的确切版本,而不是“`”中给出的版本范围。 package.json`。 (7认同)
  • 恐怕Venryx是不正确的。`npm install` **从`package-lock.json`中读取。若要进行复制,请执行以下操作。使用这个package.json,运行`npm install` {...“ devDependencies”:{“ sinon”:“ 7.2.2”}}现在复制/粘贴package.json和package-lock.json到新目录。将`package.json`更改为:“ sinon”:“ ^ 7.2.2”运行`npm install`。npm从package-lock.json读取并安装7.2.2而不是7.3.0。如果没有package-lock.json,将安装7.3.0。 (4认同)
  • @zumafra package-lock.json 文件将在执行 `npm ci` 时使用,`npm install` 将仅使用 package.json,即使提供了锁定文件 (3认同)
  • 不仅如此,而且如果您想执行类似的操作,例如将脱字符号^添加到package-lock.json中,则唯一可行的方法是删除package-lock.json并使用npm install重新生成`。(您不想手动编辑`package-lock.json`)。更改package.json的“ version”属性(在顶部附近)的值将更改npm install上的package-lock.json中的内容,但是将插入符添加到依赖项将不会做到相同到`package-lock.json`。 (2认同)
  • 将“package.json”视为您可以手动修改的内容,并将“package-lock.json”视为您永远不会手动修改的内容。您始终对两个文件进行版本控制 - 特别是“package-lock.json”。打开这两个文件,手动编辑“package.json”中的项目名称,运行“npm install”并观察“package-lock.json”中项目名称的变化。`license` 似乎没有记录在 `package-lock.json` 中。 (2认同)

zum*_*fra 7

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"
  }
}
Run Code Online (Sandbox Code Playgroud)

package-lock.json 现在将具有:

"sinon": {
  "version": "7.2.2",
Run Code Online (Sandbox Code Playgroud)

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

{
  "name": "test",
  "version": "1.0.0",
  ...
  "devDependencies": {
    "sinon": "^7.2.2"
  }
}
Run Code Online (Sandbox Code Playgroud)

运行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"
  }
}
Run Code Online (Sandbox Code Playgroud)

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

"sinon": {
  "version": "^7.3.0",
Run Code Online (Sandbox Code Playgroud)


nfl*_*aig 5

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