package-lock.json 的作用是啥?

Posted

技术标签:

【中文标题】package-lock.json 的作用是啥?【英文标题】:What is the role of the package-lock.json?package-lock.json 的作用是什么? 【发布时间】:2017-11-02 00:40:03 【问题描述】:

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

【问题讨论】:

包锁。 json 以在任何给定时间跟踪确切的依赖关系树。它将确保下载您的项目并尝试安装依赖项的所有客户端都将获得完全相同的依赖项树。 【参考方案1】:

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

来自the npm docs:

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

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

描述依赖关系树的单一表示,以保证团队成员、部署和持续集成安装完全相同的依赖关系。

为用户提供“时间旅行”到 node_modules 先前状态的工具,而无需提交目录本身。

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

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

编辑

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

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

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

注意。以前的npm-shrinkwrap.json 做了几乎相同的事情,但锁定文件对其进行了重命名,使其功能更清晰。如果项目中已经有一个收缩包装文件,那么将使用它而不是任何锁定文件。

【讨论】:

如果有一个确切版本的依赖关系如此受追捧,为什么不强制在 package.json 中指定确切版本并放弃 package-lock.json 文件? @jrahhali - 根据您的问题修改了我的答案。 如何从 pacakge.json.lock 获取这个依赖树应用到其他开发者?自动? 请注意,这个答案不再正确!自 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 文件中。 您应该添加对 npm ci 的引用,因为 npm install 将更新 package-lock.json 而 ci 使用它的内容。只有使用npm ci,您才能获得可重复的健壮构建。【参考方案2】:

这是 npm 的一项非常重要的改进:保证每个包的版本完全相同

如何确保您的项目在不同时间在不同环境中使用相同的包构建?假设您可以在您的package.json 中使用^1.2.3,或者您的一些依赖项正在使用这种方式,但是您如何确保每次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 中给出的版本范围。 恐怕 Venryx 不正确。 npm install 确实package-lock.json 读取。要重现,请执行以下操作。使用这个 package.json,运行 npm install ... "devDependencies": "sinon": "7.2.2" 现在将 package.jsonpackage-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。 不仅如此,如果你想做一些事情,比如将插入符号 ^ 添加到 package-lock.json,唯一合理的方法是删除 package-lock.json 并使用 npm install 重新生成它. (您不想手动编辑package-lock.json)。更改package.json 的“版本”属性(靠近顶部)的值将在npm install 上的package-lock.json 中更改相同的值,但在依赖项中添加插入符号不会对package-lock.json 执行相同的操作。跨度> package.json 视为您可以手动修改的东西,而将package-lock.json 视为您永远不会手动触摸的东西。你总是对两个文件进行版本控制——尤其是package-lock.json。打开这两个文件,手动编辑package.json 中的项目名称,运行npm install 并观察package-lock.json 中的项目名称如何变化。 license 似乎没有记录在package-lock.json 中。 @zumafra package-lock.json 文件将在执行npm ci 时使用,npm install 将仅使用 package.json,即使提供了锁定文件【参考方案3】:

package-lock.json 会在“版本”属性等属性中的数值或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",

【讨论】:

【参考方案4】:

package-lock.json 会自动为 npm 修改 node_modules 树或 package.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"
      
    ,
       

【讨论】:

【参考方案5】:

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

【讨论】:

【参考方案6】:

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

【讨论】:

如果我与这​​个文件发生冲突怎么办?【参考方案7】:

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

【讨论】:

您好,欢迎您。这个问题已经回答了。您必须验证问题是否已标记为已回答,看看是否有任何答案前面有绿色的勾号。 @Néstor 不要误会。鉴于答案是且有用的,因此可以回答已回答的问题。 (尽管在这个答案中并非如此)。 您提供的答案已经给出!考虑提高信息质量,使其成为有价值的答案!【参考方案8】:

package-lock.json 文件的目标是跟踪已安装的每个软件包的确切版本,以便即使软件包由其维护者更新,产品也能以相同的方式 100% 重现。

这解决了package.jsonleft 未解决的一个非常具体的问题。在 package.json 中,您可以使用 semver 表示法设置要升级到的版本(补丁或次要)。

【讨论】:

【参考方案9】:

Package.json 文件包含您安装的包和库的主要名称,您可以对其进行编辑,但 Package-lock.json 包含每个包的详细信息以及每个包的存储库链接(考虑它的详细信息来自 package.json 的包)参考

https://web-brackets.com/discussion/69/what-is-the-use-of-package-lock-json-file

【讨论】:

以上是关于package-lock.json 的作用是啥?的主要内容,如果未能解决你的问题,请参考以下文章

Vue学习系列 -- package-lock.json的作用

警报安全 Github - 修复 yarn.lock/package-lock.json 漏洞的正确方法是啥

package-lock.json 中的 "requires: true" 有啥作用

[转]npm中package-lock.json的作用:npm install安装时使用

[转]npm中package-lock.json的作用:npm install安装时使用

package.json中的版本和package-lock.json的作用