目录
package-lock.json
选择 CLI 版本
目录
描述
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
开始,其版本号对应于生成此 package-lock.json
时使用的语义。
请注意,文件格式在 npm v7 中发生了重大变化,以跟踪原本需要查看 node_modules
或 npm 注册表的信息。由 npm v7 生成的锁文件将包含 lockfileVersion: 2
。
- 未提供版本:来自 npm v5 之前的 npm 版本的“古老”shrinkwrap 文件。
1
: npm v5 和 v6 使用的锁文件版本。2
: npm v7 和 v8 使用的 lockfile 版本。向后兼容 v1 lockfile。3
: npm v9 及以上版本使用的 lockfile 版本。向后兼容 npm v7。
npm 将始终尝试从 lockfile 中获取它所能获得的任何数据,即使它不是设计为支持的版本。
packages
这是一个将包位置映射到包含该包信息的对象的對象。
根项目通常使用 ""
作为键列出,所有其他包都使用它们相对于根项目文件夹的相对路径列出。
包描述符具有以下字段
-
version: 在
package.json
中找到的版本。 -
resolved: 实际解析包的位置。对于从注册表获取的包,这将是指向 tarball 的 url。对于 git 依赖项,这将是带有提交 sha 的完整 git url。对于链接依赖项,这将是链接目标的位置。
registry.npmjs.org
是一个魔法值,表示“当前配置的注册表”。 -
integrity: 一个
sha512
或sha1
标准子资源完整性 字符串,用于在该位置解压缩的工件。 -
link: 一个标志,表示这是一个符号链接。如果存在此标志,则不会指定其他字段,因为链接目标也将包含在 lockfile 中。
-
dev, optional, devOptional: 如果包严格属于
devDependencies
树,则dev
将为 true。如果它严格属于optionalDependencies
树,则optional
将被设置。如果它既是dev
依赖项又是非开发依赖项的optional
依赖项,则devOptional
将被设置。(dev
依赖项的optional
依赖项将同时设置dev
和optional
。) -
inBundle: 一个标志,表示包是一个捆绑的依赖项。
-
hasInstallScript: 一个标志,表示包具有
preinstall
、install
或postinstall
脚本。 -
hasShrinkwrap: 一个标志,表示包具有
npm-shrinkwrap.json
文件。 -
bin, license, engines, dependencies, optionalDependencies: 来自
package.json
的字段。
dependencies
支持使用 lockfileVersion: 1
的 npm 版本的遗留数据。这是一个将包名称映射到依赖项对象的映射。由于对象结构严格是分层的,因此符号链接依赖项在某些情况下难以表示。
如果存在 packages
部分,npm v7 将完全忽略此部分,但会保持其最新状态以支持在 npm v6 和 npm v7 之间切换。
依赖项对象具有以下字段
-
version: 一个规范,根据包的性质而异,可用于获取它的新副本。
- bundled dependencies: 无论来源如何,这都是一个纯粹用于信息目的的版本号。
- registry sources: 这是一个版本号。(例如,
1.2.3
) - git sources: 这是一个带有解析的提交哈希的 git 规范。(例如,
git+https://example.com/foo/bar#115311855adb0789a0466714ed48a1499ffea97e
) - http tarball sources: 这是 tarball 的 URL。(例如,
https://example.com/example-1.3.0.tgz
) - local tarball sources: 这是 tarball 的文件 URL。(例如
file:///opt/storage/example-1.3.0.tgz
) - local link sources: 这是链接的文件 URL。(例如
file:libs/our-module
)
-
integrity: 一个
sha512
或sha1
标准子资源完整性 字符串,用于在该位置解压缩的工件。对于 git 依赖项,这是提交 sha。 -
resolved: 对于注册表源,这是相对于注册表 URL 的 tarball 的路径。如果 tarball URL 不与注册表 URL 在同一台服务器上,那么这是一个完整的 URL。
registry.npmjs.org
是一个魔法值,表示“当前配置的注册表”。 -
bundled: 如果为 true,则这是捆绑的依赖项,并将由父模块安装。安装时,此模块将在提取阶段从父模块中提取,而不是作为单独的依赖项安装。
-
dev: 如果为 true,则此依赖项是顶层模块的开发依赖项,或者是一个传递依赖项。对于既是顶层模块的开发依赖项又是顶层模块的非开发依赖项的传递依赖项的依赖项,这将为 false。
-
optional: 如果为 true,则此依赖项是顶层模块的可选依赖项,或者是一个传递依赖项。对于既是顶层模块的可选依赖项又是顶层模块的非可选依赖项的传递依赖项的依赖项,这将为 false。
-
requires: 这是一个模块名称到版本的映射。这是一个列表,其中包含此模块所需的所有内容,无论它将在哪里安装。版本应通过正常的匹配规则与我们的
dependencies
中的依赖项或比我们高一级的依赖项匹配。 -
dependencies: 此依赖项的依赖项,与顶层完全相同。