发布日期:2018 年 6 月 4 日,发布人:Aram Drevekenin
一段时间以来,JavaScript 生态系统一直托管着几种不同的依赖锁定文件格式,包括 yarn 的 yarn.lock
和 npm 的 package-lock.json
。
我们非常高兴地宣布,从 1.7.0
版本开始,yarn 本机功能 能够导入 来自 npm package-lock.json
的依赖项树,无需外部工具或笨拙的流程。
对于在混合 npm/yarn 环境中工作的开发人员或希望在现有项目上试用 yarn 的开发人员来说,这无疑是一个好消息。
你需要做的就是在一个具有 package-lock.json
文件的代码库中发出 yarn import
命令,yarn 就会使用现有 package-lock.json
文件中的解析信息,并将创建一个相应的 yarn.lock
文件。
此功能是两个软件包管理器维护者持续协作的第一个成果之一。我们强烈认为这两个工具应该意识到彼此的存在,并为它们之间提供一个轻松的过渡路径。如果你感兴趣或想提供帮助,请访问 相关的 GitHub 问题。
它的底层工作原理是什么
以前,yarn import
会依赖于软件包的 node_modules
目录来确定新 yarn.lock 文件需要将其 semver 范围解析到的固定版本。现在,如果找不到 package-lock.json
文件,它将退回到此行为。
如果找到了,yarn 将使用 npm-logical-tree 在项目根目录的 package.json
和 package-lock.json
中创建一个依赖项树。然后它使用该树中的固定版本创建自己的 yarn.lock
锁定文件。生成的 yarn.lock
将具有 package-lock.json
中指定的所有确切固定版本。准备好在代码库中安装和提交。
局限性
两种锁定文件格式和内容不同。它们都有自己的优先级,在确定性、一致性等方面的保证和权衡。由于 yarn.lock
选择仅存储逻辑依赖项树,更倾向于面向未来以进行潜在的物理树和提升优化,因此 yarn.lock
无法表示 package-lock.json
所表示的某些细微差别。
一个例子如下
// package-lock.json (slightly simplified for clarity)
{
"name": "nuanced-dependency-tree",
"dependencies": {
"a": {
"version": "9.9.9",
"requires": {
"c": "^1.0.0"
},
"dependencies": {
"c": {
"version": "1.0.1"
}
}
},
"b": {
"version": "8.8.8",
"requires": {
"c": "^1.0.0"
}
},
"c": {
"version": "1.0.5"
}
}
}
在这里,我们同时拥有软件包 a
和 b
,它们需要软件包 c
的相同 semver 范围:^1.0.0
,并获得了不同的版本:1.0.1
和 1.0.5
。
这将导入到 yarn 中,如下所示
// yarn.lock (slightly simplified for clarity)
a@9.9.9
version "9.9.9"
dependencies:
c "^1.0.0"
b@8.8.8
version "8.8.8"
dependencies:
c "^1.0.0"
c@^1.0.0
version "1.0.5"
在此,b
的依赖项 c
将其锁定的版本从 1.0.1
更改为 1.0.5
,因为 yarn.lock
无法表达这种重复。Yarn 选择并旨在为所有兼容版本范围拥有一个单一的解析版本。虽然在大多数情况下,这种小的更改不会产生太大影响 - 但我们鼓励你小心使用此功能。如果你需要,你仍然可以使用 Yarn 中的选择版本解析功能 来覆盖范围。
未来计划
目前,我们正计划向同时使用 yarn
和 npm
安装软件包的同一存储库中的用户添加一些警告。如有需要,我们可能还会尝试将此功能扩展到其他锁定文件格式。如果你想指出其他互操作性问题或尝试修复这些问题 - 我们鼓励你在 文件中提出问题 或发送 PR 更好地 修复其中一个。
如果你决定使用 Yarn,我们强烈建议你删除 package-lock.json
文件,以避免将来混淆和可能的连贯性问题.