npm:引用对等依赖;如何从对等依赖项中对齐版本
npm: refer to a peer dependency; how to align the version from a peer dependency
总而言之,我对提供的 dependency-B
版本没意见,感谢 dependency-A
。
已经安装了该版本
"dependencies": {
"dependency-A": "x.y.z",
}
$> npm ls --depth=1
├─┬ dependency-A@x.y.z
│ ├── dependency-B@x.y.z
所以当我 require('dependency-B')
时,我会期待 A 的 依赖。
我正在使用该库中的根函数,事实上,如果 dependency-A
改变了版本,我想与其保持一致并使用它使用的相同版本。
如果 dependency-B
列在依赖项中,将安装一个全新的包。
"dependencies": {
"dependency-A": "x.y.z",
"dependency-B": "a.b.c",
}
$> npm ls --depth=1
├─┬ dependency-A@x.y.z
│ ├── dependency-B@x.y.z
│ ├── ...
├─┬ dependency-B@a.b.c
我很想不列出 dependency-B
我的依赖项。我应该避免这种做法吗?依赖我主依赖安装的peer版本不行吗?
如果这是一种粗鲁的做法,我如何告诉 npm 给我与另一个包安装的完全相同的版本?
"dependencies": {
"dependency-A": "x.y.z",
"dependency-B": "~try the one that is installing dependency-A~",
}
tl;dr: You should always have all dependencies that you're using in your own dependencies
object, as conformant implementations of package managers are not required to give you access to your dependencies' dependencies.
这是一个有趣的问题,我可以想到您可能会遇到的两种情况:
- 您的包和
dependency-A
都独立使用 dependency-B
,出于您自己的一系列原因,您根本不关心使用哪个版本。
- 您需要使用
dependency-B
才能与 dependency-A
交互,方法是创建 B 的对象或接收 A 创建的 B 的对象。
场景一:独立使用
如果您和您的依赖项需要同一个包但不需要共享它的任何内容,Node 为您提供了惊人的能力,通过在 package.json
你的包和你的图书馆的。这是Node模块系统的优势之一。
但是,您的情况是您不关心包的实际版本(这让我认为这不是您的情况)。特别是,您想知道 不 在您自己的 package.version
中定义任何东西并让 Node 找到您的依赖关系是否更好。
最后一种情况之所以可能,是因为您正在使用 npm
,并且 npm
做了一件特定的事情:它展平模块树以消除重复包,也就是说,同一版本可以满足的多个依赖规范,最终使用的是完全相同的版本。这减少了模块树的大小和深度,但会产生意想不到的后果,即您现在可以访问未指定为依赖项的包,只是因为它们是为了重复数据删除而安装在您的 node_modules
目录中。
虽然这不是唯一可能的策略,但另一个包管理器 pnpm
使用符号链接来实现相同的目标。我不会详细介绍,但是 pnpm
将所有依赖项安装在不同的系统范围(或用户特定的)目录中,然后从您的 node_modules
(以及依赖项自己的node_modules
) 到该文件夹中的适当位置。这不仅实现了项目方面的重复数据删除,而且实现了系统范围的重复数据删除,因为所有使用特定包版本的项目将使用相同的安装 .然而,这个系统的后果是你“失去”了在你自己的包中使用你的依赖项的依赖项的能力,因为它们不再物理地在 node_modules
.
除此之外,您不关心他们使用的版本。几乎从来没有这种情况,因为语义版本控制的全部意义在于避免或包含由于依赖版本升级而导致的破坏。您不关心您现在使用的版本,但如果该包在您的依赖项中升级到不同的主要版本,您的包可能会意外中断。
总而言之,不定义您将要使用的依赖项是一种不好的做法,这既是因为它会阻止其他开发人员在不同的包管理器中使用您的包,又因为它会让您面临意外的破坏将无法妥善管理。
场景 2:依赖用法
根据您对问题的描述,更有可能的情况是,在您使用 dependency-A
的某个时刻,它要么请求某些东西,要么 returns 来自 dependency-B
的东西。在这种情况下,希望两者都使用相同或至少兼容的版本,以便所有关于正在交换的对象形状的假设都成立。
指定这种情况的正确方法是将 dependency-B
显式声明为 dependency-A
的对等依赖项。如果情况并非如此,那么它们就是不正确的,如果可能的话,您绝对应该在问题中提出来。作为一种解决方法,您可以只声明与他们相同的版本,并警惕由于他们的版本升级而可能造成的破坏。不在您自己的 package.json
中定义任何内容可能会遇到与方案 1 中相同的问题。
然而,另一种可能性是您甚至不需要require
那个依赖。情况可能是他们希望您传递数据、函数、对象或任何将进一步传递给 dependency-b
的东西,但以一种使您不必直接与 dependency-B
交互的方式。在这种情况下,他们实际上是将 B 的 API 的一部分合并到他们自己的 dependency-B
中,因此 dependency-B
的任何重大更改也应该导致 dependency-A
的重大更改。这可以保护您免受意外损坏,避免您必须在 package.json
中定义任何内容,这意味着您是安全的。
总而言之,我对提供的 dependency-B
版本没意见,感谢 dependency-A
。
"dependencies": {
"dependency-A": "x.y.z",
}
$> npm ls --depth=1
├─┬ dependency-A@x.y.z
│ ├── dependency-B@x.y.z
所以当我 require('dependency-B')
时,我会期待 A 的 依赖。
我正在使用该库中的根函数,事实上,如果 dependency-A
改变了版本,我想与其保持一致并使用它使用的相同版本。
如果 dependency-B
列在依赖项中,将安装一个全新的包。
"dependencies": {
"dependency-A": "x.y.z",
"dependency-B": "a.b.c",
}
$> npm ls --depth=1
├─┬ dependency-A@x.y.z
│ ├── dependency-B@x.y.z
│ ├── ...
├─┬ dependency-B@a.b.c
我很想不列出 dependency-B
我的依赖项。我应该避免这种做法吗?依赖我主依赖安装的peer版本不行吗?
如果这是一种粗鲁的做法,我如何告诉 npm 给我与另一个包安装的完全相同的版本?
"dependencies": {
"dependency-A": "x.y.z",
"dependency-B": "~try the one that is installing dependency-A~",
}
tl;dr: You should always have all dependencies that you're using in your own
dependencies
object, as conformant implementations of package managers are not required to give you access to your dependencies' dependencies.
这是一个有趣的问题,我可以想到您可能会遇到的两种情况:
- 您的包和
dependency-A
都独立使用dependency-B
,出于您自己的一系列原因,您根本不关心使用哪个版本。 - 您需要使用
dependency-B
才能与dependency-A
交互,方法是创建 B 的对象或接收 A 创建的 B 的对象。
场景一:独立使用
如果您和您的依赖项需要同一个包但不需要共享它的任何内容,Node 为您提供了惊人的能力,通过在 package.json
你的包和你的图书馆的。这是Node模块系统的优势之一。
但是,您的情况是您不关心包的实际版本(这让我认为这不是您的情况)。特别是,您想知道 不 在您自己的 package.version
中定义任何东西并让 Node 找到您的依赖关系是否更好。
最后一种情况之所以可能,是因为您正在使用 npm
,并且 npm
做了一件特定的事情:它展平模块树以消除重复包,也就是说,同一版本可以满足的多个依赖规范,最终使用的是完全相同的版本。这减少了模块树的大小和深度,但会产生意想不到的后果,即您现在可以访问未指定为依赖项的包,只是因为它们是为了重复数据删除而安装在您的 node_modules
目录中。
虽然这不是唯一可能的策略,但另一个包管理器 pnpm
使用符号链接来实现相同的目标。我不会详细介绍,但是 pnpm
将所有依赖项安装在不同的系统范围(或用户特定的)目录中,然后从您的 node_modules
(以及依赖项自己的node_modules
) 到该文件夹中的适当位置。这不仅实现了项目方面的重复数据删除,而且实现了系统范围的重复数据删除,因为所有使用特定包版本的项目将使用相同的安装 .然而,这个系统的后果是你“失去”了在你自己的包中使用你的依赖项的依赖项的能力,因为它们不再物理地在 node_modules
.
除此之外,您不关心他们使用的版本。几乎从来没有这种情况,因为语义版本控制的全部意义在于避免或包含由于依赖版本升级而导致的破坏。您不关心您现在使用的版本,但如果该包在您的依赖项中升级到不同的主要版本,您的包可能会意外中断。
总而言之,不定义您将要使用的依赖项是一种不好的做法,这既是因为它会阻止其他开发人员在不同的包管理器中使用您的包,又因为它会让您面临意外的破坏将无法妥善管理。
场景 2:依赖用法
根据您对问题的描述,更有可能的情况是,在您使用 dependency-A
的某个时刻,它要么请求某些东西,要么 returns 来自 dependency-B
的东西。在这种情况下,希望两者都使用相同或至少兼容的版本,以便所有关于正在交换的对象形状的假设都成立。
指定这种情况的正确方法是将 dependency-B
显式声明为 dependency-A
的对等依赖项。如果情况并非如此,那么它们就是不正确的,如果可能的话,您绝对应该在问题中提出来。作为一种解决方法,您可以只声明与他们相同的版本,并警惕由于他们的版本升级而可能造成的破坏。不在您自己的 package.json
中定义任何内容可能会遇到与方案 1 中相同的问题。
然而,另一种可能性是您甚至不需要require
那个依赖。情况可能是他们希望您传递数据、函数、对象或任何将进一步传递给 dependency-b
的东西,但以一种使您不必直接与 dependency-B
交互的方式。在这种情况下,他们实际上是将 B 的 API 的一部分合并到他们自己的 dependency-B
中,因此 dependency-B
的任何重大更改也应该导致 dependency-A
的重大更改。这可以保护您免受意外损坏,避免您必须在 package.json
中定义任何内容,这意味着您是安全的。