package.lock.json 到底有什么用?

简介: 目前的前端现代工程化中,npm 的生态已经成为密不可分的一环,而每个基于 npm 包的项目的 npm init 之后,都会有一个 package.json,在 npm install 之后又会有一个 package-lock.json,它们极为相似的名称让我很感兴趣,package-lock.json 究竟是何方神圣?毕竟平常我只修改 package.json

目前的前端现代工程化中,npm 的生态已经成为密不可分的一环,而每个基于 npm 包的项目的 npm init 之后,都会有一个 package.json,在 npm install 之后又会有一个 package-lock.json,它们极为相似的名称让我很感兴趣,package-lock.json 究竟是何方神圣?毕竟平常我只修改 package.json

IMG

什么?你问我为什么不直接“操作” package-lock.json

这么长的文件,我看都不想看/(ㄒoㄒ)/~~

IMG

简介

关于 package-lock.json 的介绍比较权威的可以参考 npm Docspackage-lock.json

对于基于 npm 修改 node_modules 树或者 package.json 的任何操作,都会自动生成 package-lock.json。它描述了生成的确切树,以便后续安装能够生成相同的树,而不考虑中间的依赖关系更新。 此文件旨在提交到源存储库中,并用于各种目的:

  1. 描述依赖关系树的单一表示,以确保队友、部署和持续集成能够安装完全相同的依赖关系。
  2. 为用户提供一种工具,让他们“时间旅行”到node_module的先前状态,而不必提交目录本身。
  3. 通过可读的源代码控制差异,提高树更改的可见性。
  4. 通过允许npm跳过先前安装的包的重复元数据解析,优化安装过程。
  5. 从npm v7开始,锁定文件包含了足够的信息来获得包树的完整图片,从而减少了读取包的需要。json文件,并允许显著的性能改进。

结构

IMG

上面这张图是 package.lock.json 的属性描述,文章将只挑几个重要的介绍,而详细部分可以参考 package-lock.json - npm Docs

其中 nameversion 属性是源自 package.json 文件,如果不一致则可能是修改了 package.json 同时再也没有 npm 的相关操作

啥操作能够引起 package-lock.json 的更新?比如 npm uninstall | npm install ...

lockfileVersionnpm 对于 package.lock.json 的一个版本号,比如

  1. npm V5 and npm V61
  2. 兼容 npm V7 及以前的 npm 版本的 package.lock.jsonnpm 版本是 2
  3. npm V7 以上且不兼容 npm V7 以前的 npm 版本的 package.lock.jsonnpm 版本是 3

然后就来到了 package.lock.json 最重要的的属性,它是 package.lock.json 作用的体现

安装完全相同的依赖关系

这也是为什么叫 *.lock.* 的原因,就是锁住 node_modules,让项目中的其它成员在远程拉去代码的时候能够安装相同的 node_moduels

其实现就是依靠 packages 属性,来看一下 packages 的结构

202212311447013.png

实际的 package.lock.jsonpackages 如下

{
  // ...
  "packages": {
    "node_modules/prettier": {
      "version": "2.8.0",
      "resolved": "https://registry.npmmirror.com/prettier/-/prettier-2.8.0.tgz",
      "integrity": "sha512-9Lmg8hTFZKG0Asr/kW9Bp8tJjRVluO8EJQVfY2T7FMw9T5jy4I/Uvx0Rca/XWf50QQ1/SS48+6IJWnrb+2yemA==",
      "bin": {
        "prettier": "bin-prettier.js"
      },
      "engines": {
        "node": ">=10.13.0"
      }
    },
  },
  // ...
}

对应的 package.json

{
  // ...
  "dependencies": {
    // ...
    "prettier": "^2.8.0"
  }
}

你会发现,prettierversion^2.8.0 变到了 2.8.0,这里就要科普一下对于 Node 来说 ^ 这种模块版本前缀的含义了

~x.y.z: 匹配大于 x.y.z 的 z 的最新版
^x.y.z: 匹配大于 x.y.z 的 y.z 的最新版
*: 任意版本,一般是最后一次正式发布版本(包括非 latest tag),不是最大版本号版本

总而言之,以 ^ | ~ | * 作为前缀的版本号都是表示一个范围区间的所有版本号,而不是一个确定的版本号,比如 ^2.8.0,它可以被安装为 2.9.02.8.1 或者 2.9.1...,而 2.8.0 就只能是 2.8.0

因此 packagesnpm 提供了一个固定的版本值,在其它项目成员去 npm install 的时候都会得到同样的 node_modules,保证了开发时的一致

参考资料

  1. package-lock.json - npm Docs
  2. 详解package.json和package-lock.json - 苏苏同学 - 掘金
  3. package.json 与 package-lock.json 的关系 - 阿离王 - 掘金
相关文章
|
6月前
|
JavaScript
package.json 和 package-lock.json
package.json 和 package-lock.json
33 0
|
2天前
package.json和package-lock.json简介
package.json和package-lock.json简介
|
4月前
|
资源调度 前端开发 JavaScript
初识package.json,两个重要字段不能忽略
初识package.json,两个重要字段不能忽略
|
11月前
|
资源调度 JavaScript 开发者
关于项目中的package.json的介绍
关于项目中的package.json的介绍
96 0
|
11月前
|
前端开发
package.json 中的配置
package.json 中的配置
84 0
|
缓存 JavaScript 前端开发
详解package.json和package-lock.json
package.json和package-lock.json
821 0
|
JSON JavaScript 数据格式
JSON.parse和evel的区别
JSON.parse和evel的区别
68 0
|
编解码 JSON 缓存
package-lock.json 文件介绍|学习笔记
快速学习 package-lock.json 文件介绍
615 0