你需要知道的关于package-lock.json

8,270 阅读2分钟
原文链接: zhuanlan.zhihu.com

什么时候产生的?

如果你的NPM升级到v5.x.x版本, 你就会发现一个新的文件会自动创建, Package-lock.json.

在Package-lock刚开始时候, 有一些问题. 比如:模块找不到或者安装了错误版本的依赖。

Missing dependencies after running `npm install` a second time · Issue #16839 · npm/npm​github.com图标 package-lock.json file not updated after package.json file is changed · Issue #16866 · npm/npm​github.com图标

大多数这时候我们可能会通过删除package-lock文件, 然后重新执行npm install解决问题。

不过这个问题已经在npm/issue/17058修复了.

Lock missing dep fixes by iarna · Pull Request #17508 · npm/npm​github.com图标

为什么需要package-lock?

在讲述之前我们需要了解一个东西叫做语义化版本.

语义化版本 2.0.0​semver.org

简单理解: XYZ 的格式

对应为: 主版本号.次版本号.修订号,版本号递增规则如下:

主版本号:当你做了不兼容的 API 修改,

次版本号:当你做了向下兼容的功能性新增,

修订号:当你做了向下兼容的问题修正。

举例理解为什么需要package-lock锁.

假设我们创建了一个新项目,它将使用express。 在运行npm init之后,在撰写本项目时,最新的express版本是4.15.4。 (默认情况下,npm 将安装最新版本)

因此在package.json中,"express":"^ 4.15.4"被添加作为依赖项。 假设明天,express的维护者会发布一个 bug 修复,所以最新版本变成了4.15.5。 然后,如果有人想要为我的项目做贡献,他们会克隆它,然后运行 npm install, 因为4.15.5是一个更高版本的主要版本,这是为他们安装的。 我们都有express依赖,但我们有两个不同的版本。 理论上,它们应该还是兼容的,但是也许这个 bug 会影响我们正在使用的功能,而我们的应用程序在使用Express版本4.15.4与4.15.5进行比较时会产生不同的结果.

而package-lock.json的作用就是用来保证我们的应用程序依赖之间的关系是一致的, 兼容的.

它是如何工作的?

package-lock.json指定了每个模块及其每个依赖项的版本、位置和完整哈希(hash),所以不管你使用什么设备(跨平台),什么时候.每一次执行npm install时候安装的依赖都是相同的.

以express为例:看看lock的格式:

 "express": {
    "version": "4.15.4",
    "resolved": "https://registry.npmjs.org/express/-/express-4.15.4.tgz",
    "integrity": "sha1-Ay4iU0ic+PzgJma+yj0R7XotrtE=",
    "requires": {
      "accepts": "1.3.3",
      "array-flatten": "1.1.1",
      "content-disposition": "0.5.2",
      "content-type": "1.0.2",
      "cookie": "0.3.1",
      "cookie-signature": "1.0.6",
      "debug": "2.6.8",
      "depd": "1.1.1",
      "encodeurl": "1.0.1",
      "escape-html": "1.0.3",
      "etag": "1.8.0",
      "finalhandler": "1.0.4",
      "fresh": "0.5.0",
      "merge-descriptors": "1.0.1",
      "methods": "1.1.2",
      "on-finished": "2.3.0",
      "parseurl": "1.3.1",
      "path-to-regexp": "0.1.7",
      "proxy-addr": "1.1.5",
      "qs": "6.5.0",
      "range-parser": "1.2.0",
      "send": "0.15.4",
      "serve-static": "1.12.4",
      "setprototypeof": "1.0.3",
      "statuses": "1.3.1",
      "type-is": "1.6.15",
      "utils-merge": "1.0.0",
      "vary": "1.1.1"
    }
  },

值得注意的是require字段: 它是在[issue/17058]引入的,用于跟踪给定模块需要的模块。