npm package-lock.json
描述
package-lock.json
对于任何 npm 修改node_modules
树或package.json
. 它描述了生成的确切树,以便后续安装能够生成相同的树,而不管中间依赖项更新如何。
此文件旨在提交到源存储库中,并用于多种目的:
- 描述依赖树的单一表示,以便保证团队成员、部署和持续集成安装完全相同的依赖关系。
- 为用户“时间旅行”到以前的状态提供便利,
node_modules
而无需提交目录本身。 - 通过可读的源代码控制差异提高树更改的可见性。
- 通过允许 npm 跳过先前安装的包的重复元数据解析来优化安装过程。
- 从 npm v7 开始,锁文件包含足够的信息来获得包树的完整图片,减少读取
package.json
文件的需要,并允许显着的性能改进。
package-lock.json
对比 npm-shrinkwrap.json
这两个文件具有相同的格式,并且在项目的根目录中执行类似的功能。
不同的是package-lock.json
不能发布,如果在根项目以外的任何地方发现都会被忽略。
相比之下,npm-shrinkwrap.json允许发布,并从遇到的点定义依赖树。除非部署 CLI 工具或以其他方式使用发布过程来生成生产包,否则不建议这样做。
如果package-lock.json
和npm-shrinkwrap.json
都存在于项目的根目录中,npm-shrinkwrap.json
则将优先并被 package-lock.json
忽略。
隐藏的锁文件
为了避免node_modules
重复处理文件夹,从 v7 开始,npm 使用存在于 node_modules/.package-lock.json
. 这包含有关树的信息,node_modules
如果满足以下条件,则用于代替读取整个层次结构:
它引用的所有包文件夹都存在于node_modules
层次结构中。node_modules
层次结构中不存在未在锁定文件中列出的包文件夹。文件的修改时间至少与其引用的所有包文件夹一样近。也就是说,隐藏的锁文件只有在作为包树的最新更新的一部分创建时才相关。如果另一个 CLI 以任何方式改变树,这将被检测到,隐藏的锁文件将被忽略。
注意,它是可以手动改变内容在这样一种方式,包文件夹的修改的时间是不受影响的封装的。例如,如果您将文件添加到node_modules/foo/lib/bar.js
,则修改时间node_modules/foo
不会反映此更改。如果您在 中手动编辑文件node_modules
,通常最好删除 中的文件node_modules/.package-lock.json
。
由于较旧的 npm 版本会忽略隐藏的锁文件,因此它不包含“普通”锁文件中存在的向后兼容性可供性。也就是说,它是lockfileVersion: 3
,而不是 lockfileVersion: 2
。
处理旧的锁文件
当 npm 在包安装过程中从 npm v6 或之前检测到锁文件时,它会自动更新以从node_modules
树或(在空node_modules
树或非常旧的锁文件格式的情况下 )npm 注册表中获取丢失的信息。
文件格式
name
这是一个包锁的包的名称。这将匹配package.json
.
version
这是一个包锁的包的版本。这将匹配package.json
.
lockfileVersion
一个整数版本,从1
这个文档的版本号开始,在生成 this 时使用了它的语义 package-lock.json
。
请注意,npm v7 中的文件格式发生了重大变化,以跟踪原本需要查看node_modules
npm 注册表的信息。npm v7 生成的锁文件将包含 lockfileVersion: 2
.
未提供版本:来自 npm v5 之前的 npm 版本的“古老”收缩包装文件。1
:npm v5 和 v6 使用的锁文件版本。2
:npm v7 使用的锁文件版本,向后兼容 v1 锁文件。3
:npm v7 使用的锁文件版本,没有向后兼容性可供性。这用于隐藏的锁文件 node_modules/.package-lock.json
,一旦不再支持 npm v6,很可能会在 npm 的未来版本中使用。npm 将始终尝试从锁定文件中获取它可以获取的任何数据,即使它不是它旨在支持的版本。
packages
这是一个将包位置映射到包含有关该包的信息的对象的对象。
根项目通常以 键列出""
,所有其他包都以它们从根项目文件夹的相对路径列出。
包描述符具有以下字段:
- 版本:找到的版本
package.json
- 已解析:实际解析包的位置。对于从注册表获取的包,这将是一个指向 tarball 的 url。对于 git 依赖项,这将是带有 commit sha 的完整 git url。在链接依赖的情况下,这将是链接目标的位置。
- 完整性: 在此位置解包的工件的
sha512
或sha1
标准子资源完整性字符串。 - 链接:一个标志,表明这是一个符号链接。如果存在,则不指定其他字段,因为链接目标也将包含在锁定文件中。
- dev, optional, devOptional:如果包严格地是
devDependencies
树的一部分,则为dev
真。如果它严格是optionalDependencies
树的一部分,optional
则将被设置。如果它既是一个dev
依赖性和一个optional
非开发依赖的相关性,然后devOptional
将被设置。(optional
依赖项的dev
依赖项将同时设置dev
和optional
设置。) - inBundle:指示包是捆绑依赖项的标志。
- hasInstallScript:一个标志,以表明该封装具有
preinstall
,install
或postinstall
脚本。 - hasShrinkwrap:一个标志,表明包有一个
npm-shrinkwrap.json
文件。 - bin、license、engines、dependencies、optionalDependencies:来自的字段
package.json
依赖
用于支持使用lockfileVersion: 1
. 这是包名到依赖对象的映射。因为对象结构是严格分层的,符号链接依赖在某些情况下很难表示。
如果某个packages
部分存在,npm v7 会完全忽略该部分,但会使其保持最新状态以支持在 npm v6 和 npm v7 之间切换。
依赖对象具有以下字段:
- version:根据包的性质而变化的说明符,可用于获取它的新副本。
- 捆绑依赖项:无论来源如何,这是一个纯粹用于提供信息目的的版本号。
- 注册表源:这是一个版本号。(例如,
1.2.3
) - git 来源:这是一个 git 说明符,具有已解决的 committish。(例如,
git+https://example.com/foo/bar#115311855adb0789a0466714ed48a1499ffea97e
) - http tarball 来源:这是 tarball 的 URL。(例如,
https://example.com/example-1.3.0.tgz
) - 本地 tarball 源:这是 tarball 的文件 URL。(例如
file:///opt/storage/example-1.3.0.tgz
) - 本地链接源:这是链接的文件 URL。(例如
file:libs/our-module
)
- 完整性: 在此位置解包的工件的
sha512
或sha1
标准子资源完整性字符串。对于 git 依赖项,这是提交 sha。 - 已解析:对于注册表源,这是相对于注册表 URL 的 tarball 路径。如果 tarball URL 与注册表 URL 不在同一台服务器上,那么这是一个完整的 URL。
- bundled:如果为 true,则这是捆绑的依赖项,将由父模块安装。安装时,这个模块会在提取阶段从父模块中提取出来,而不是作为单独的依赖项安装。
- dev: 如果为真,那么这个依赖要么是顶层模块的开发依赖,要么是一个的传递依赖。对于既是顶级开发依赖又是顶级非开发依赖的传递依赖的依赖,这是错误的。
- 可选:如果为真,那么这个依赖要么是顶层模块的可选依赖,要么是一个的传递依赖。对于既是顶层的可选依赖又是顶层非可选依赖的传递依赖的依赖,这是错误的。
- 要求:这是模块名称到版本的映射。这是此模块所需的所有内容的列表,无论它将安装在哪里。版本应该通过正常匹配规则匹配我们
dependencies
或比我们更高级别的依赖项。 - 依赖:这个依赖的依赖,和顶层完全一样。
更多建议: