日常使用中,我们执行 npm install来下载项目所属依赖,很少在意过package-lock.json。虽然我们知道它是用来锁定版本的,但是每当我们添加新依赖时,package-lock.json也会更新。那么,它的锁定功能到底在什么时候起作用呢?

package.json

首先了解下 package.json中的版本说明,如:

  1. {
  2. "dependencies": {
  3. "vue": "^3.2.25"
  4. }
  5. }

依赖的版本号都是由三段数字组成,分别是主版本号(major version),次版本号(minor version)和bug修复/补丁版本号(bug fix/patch version)

在版本号的头部字符^代表通过npm install可以安装最新的次版本号依赖,如果最新次版本是 3.3.2则会安装该版本,如果最新版本是 4.1.2,则不会安装,因为只能大于等于次版本。如果是 ~,则可以安装大于等于最新的补丁版本,理由同上。如果版本号前不加任何字符,则安装指定版本。

因此,仅使用 package.json安装依赖可能导致其他人安装的依赖与原项目依赖不一样,我们需要一种能够严格限制依赖版本的方法。

package-lock.json

package-lock.json作用是严格限制依赖版本,其内容与 node_modules 实际安装的版本版本一致。
npm install的作用是确认**package.json****package-lock.json**中声明的内容是否一致,当一致时,执行 npm install会完全按照后者的声明内容安装依赖,就像 npm ci。当不一致时,以 package.json为准,就像执行 npm install some-pkg@x.y.z,而x.y.z来自package.json

举例

假设最新主版本是 2.1.1,次版本是 1.2.1,补丁版本是 1.1.9,执行 npm install,会安装哪个版本?

package.json package-lock.json node_modules(实际安装的依赖版本)
1 ^1.1.1 1.1.1
2 ^1.1.1 1.1.2
3 ^1.1.1 1.1.0
4 ~1.1.1 1.2.1
package.json package-lock.json node_modules
1 ^1.1.1 1.1.1 1.1.1
2 ^1.1.1 1.1.2 1.1.2
3 ^1.1.1 1.1.0 1.2.1
4 ~1.1.1 1.2.1 1.1.9
  1. package.json中声明 ^1.1.1代表可以次版本安装 **1.1.1**及以上package-lock.json中的版本是 1.1.1,两者声明符合,因此以 package-lock.json为准,安装 1.1.1版本。
  2. 道理同一,package-lock.json1.1.2,符合package.json中声明的 ^1.1.1
  3. package-lock.json声明 1.1.0,而 package.json则要求大于等于 1.1.1版本,两者不符合,因此以 package.json为准,安装大于等于 1.1.1的最新次版本 1.2.1
  4. package.json要求补丁版本安装 **1.1.1**及以上package-lock.json不符合要求,以package.json为准,安装大于等于 1.1.1的最新补丁版本 1.1.9

    总结

    package.jsonpackage-lock.json一致时,依照 package-lock.json安装依赖;否则按照 package.json,同时更新 package-lock.json为符合package.json要求的版本。

    参考

  5. https://dev.to/saurabhdaware/but-what-the-hell-is-package-lock-json-b04