为什么在npm中使用对等的依赖关系呢?

为什么例如一个Grunt插件将其依赖于grunt定义为“peer dependencies”?

为什么插件不能在grunt-plug / node_modules中使用Grunt作为自己的依赖项?

同行依赖关系在这里描述: https : //nodejs.org/en/blog/npm/peer-dependencies/

但我真的不明白。

我现在正在使用AppGyver类固件,它使用Grunt任务将我的源文件构build到/ dist /文件夹中,以便在本地设备上提供。 我在npm和grunt方面很新,所以我想完全理解发生了什么。

到目前为止,我得到这个:

[rootfolder] /package.json告诉npm它取决于grunt-steroids npm包进行开发:

"devDependencies": { "grunt-steroids": "0.x" }, 

好的。 在[rootfolder]中运行npm install检测依赖关系,并在[rootfolder] / node_modules / grunt-steroids中安装grunt-steroids

然后Npm读取[rootfolder] /node_modules/grunt-steroids/package.json,以便安装grunt-steroids自己的依赖项。

 "devDependencies": { "grunt-contrib-nodeunit": "0.3.0", "grunt": "0.4.4" }, "dependencies": { "wrench": "1.5.4", "chalk": "0.3.0", "xml2js": "0.4.1", "lodash": "2.4.1" }, "peerDependencies": { "grunt": "0.4.4", "grunt-contrib-copy": "0.5.0", "grunt-contrib-clean": "0.5.0", "grunt-contrib-concat": "0.4.0", "grunt-contrib-coffee": "0.10.1", "grunt-contrib-sass": "0.7.3", "grunt-extend-config": "0.9.2" }, 

嗯k。 “依赖关系”软件包被安装到[rootfolder] / node_modules / grunt-steroids / node_modules中 ,这对我来说是合乎逻辑的。“devDependencies”没有被安装,我确信是由npm控制的。 使用 grunt-steroids,而不是发展。

但是,我们有“同伴依赖”。

这些安装在[rootfolder] / node_modules ,我不明白为什么有和不在[rootfolder] / node_modules / grunt-steroids / node_modules ,以避免与其他grunt插件(或其他)的冲突?

TL; DR: peerDependencies是用于消费代码的依赖关系,而不是隐藏的“私有”依赖关系,只是一个实现细节。

问题同伴依赖解决

NPM的模块系统是分层的。 简单场景的一大优势是,当你安装一个NPM软件包时,这个软件包会带来它自己的依赖关系,所以它可以开箱即用。

但是当出现以下问题时

  • 您的项目和您正在使用的某个模块都依赖于相同的其他模块。
  • 三个模块必须相互交谈。

假设您正在构buildYourCoolProject并使用JacksModule 1.0JillsModule 2.0 。 假设JacksModule也依赖于JillsModule ,但是在不同的版本上,比如说1.0 。 只要这两个版本不符合,就没有问题。 JillsModule在表面下使用JillsModule的事实只是一个实现细节。 我们捆绑JillsModule两次JillsModule ,但是当我们获得稳定的软件时,这是一个小的代价。

但是现在让我们假设JillsModule以某种方式公开它对JacksModule的依赖。 instanceof它接受一个对象instanceof JillsClass …当我们使用库的2.0版本创build一个new JillsClass并将其传递给jacksFunction什么? 所有的地狱都会破裂! 简单的事情,如jillsObject instanceof JillsClass会突然返回false ,因为jillsObject实际上是另一个 JillsClass2.0版本)的实例。

同伴依赖如何解决这个问题

他们告诉NPM'我需要这个软件包,但是我需要的版本是项目的一部分,而不是我的模块的私有版本'。 当NPM发现你的软件包被安装到一个没有这个依赖关系的项目中,或者它有一个不兼容的版本时,它会在安装过程中警告用户。

你应该什么时候使用peer dependencies?

  • 当你build立一个图书馆供其他项目使用时,
  • 这个库正在使用一些其他的库,
  • 您希望/需要用户与其他库一起工作

常见的场景是大型框架的插件。 想象一下Gulp,Grunt,Babel,Mocha等等。如果你写一个Gulp插件,你希望这个插件和用户项目使用的Gulp一起工作,而不是用你自己的Gulp私有版本。

我会build议你先阅读文章。 这有点令人困惑,但winston邮件的例子显示你的答案为什么:

例如,让我们假装winston邮件0.2.3在其“依赖关系”散列中指定了“winston”:“0.5.x”,因为这是它testing的最新版本。 作为一名应用程序开发人员,您需要最新,最好的东西,所以您可以查看最新版本的Winston和Winston-mail,并将它们放入package.json中

 { "dependencies": { "winston": "0.6.2", "winston-mail": "0.2.3" } } 

但现在,运行npm install会导致意外的依赖关系图

 ├── winston@0.6.2 └─┬ winston-mail@0.2.3 └── winston@0.5.11 

在这种情况下,可能会有多个版本的包会导致一些问题。 peerDependencies允许npm开发人员确保用户具有特定的模块(在rootfolder中)。 但是你的观点是正确的,即描述一个特定版本的软件包会导致其他软件包使用其他版本的问题。 正如文章所述,这个问题与npm开发者有关

其中一条build议是:对于依赖关系的需求,与对常规依赖关系的要求不同,应该是宽松的。 您不应将对等关系locking到特定的修补程序版本。

因此开发者应该遵循semver来定义peerDependencies。 你应该在github上打开grunt-steriods软件包的问题…

正如Blueprint官方所说,如果你看到UNMET PEER DEPENDENCY错误,你应该手动安装React:

npm install --save react react-dom react-addons-css-transition-group

你可以在这里find它