提问者:小点点

为什么在npm中为插件使用对等依赖关系?


例如,为什么一个Grunt插件将它对Grunt的依赖定义为“对等依赖”?

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

对等项依赖关系描述如下:https://nodejs.org/en/blog/npm/peer-dependencies/

但我真的不明白。

示例

目前我正在使用AppGyver Steroids,它使用Grunt任务将源文件构建到/dist/文件夹中,以便在本地设备上提供。我是npm和grunt的新手,所以我想完全理解正在发生的事情。

到目前为止我得到的是:

[rootfolder/package.json告诉npm它依赖于npm包进行开发:

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

好吧。在[rootfolder]中运行npm安装将检测到依赖项,并在[rootfolder/node_modules/grunt-steroids中安装grunt-steroids。

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

"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"
  },

“dependencies”包被安装到[rootfolder/node_modules/grunt-steroids/node_modules]中,这对我来说是合乎逻辑的。

没有安装“devdependencies”,我确定它是由npm检测控制的。我只是尝试使用,而不是在它上开发。

但我们有了“贵族”。

这些插件都安装在[rootfolder/node_modules/grunt-steroids/node_modules中,我不明白为什么会在[rootfolder/node_modules/grunt-steroids/node_modules中而不是在[rootfolder/node_modules/grunt中,这样就可以避免与其他grunt插件(或


共3个答案

匿名用户

TLDR:用于向消费代码公开(并预期由消费代码使用)的依赖项,而不是未公开的“私有”依赖项,它只是一个实现细节。

NPM的模块系统是分层的。简单场景的一大优势是,当您安装npm包时,该包自带依赖项,因此可以开箱即用。

但在下列情况下就会出现问题:

  • 您的项目和您正在使用的某个模块都依赖于另一个模块。/li>

假设您正在构建,并且使用了。假设也依赖于,但依赖于不同的版本,比如。只要那2个版本不满足就没有问题。在表面下面使用这一事实只是一个实现细节。我们将捆绑了两次,但是当我们得到稳定的软件时,这是一个很小的代价。

但是现在,如果以某种方式公开了它对的依赖关系,该怎么办。例如,它接受的实例。当我们使用库的版本创建一个并将其传递给时会发生什么?所有的地狱都会崩溃!像这样简单的东西会突然返回,因为实际上是另一个的实例,即版本。

他们告诉npm

我需要这个包,但我需要的版本是项目的一部分,而不是我的模块私有的一些版本。

当npm发现您的软件包正在安装到一个不具有该依赖关系的项目中,或者安装到一个不兼容版本的项目中时,它将在安装过程中向用户发出警告。

  • 当您正在生成要由其他项目使用的库时,以及/li>

常见的场景是用于较大框架的插件。想想Gulp,Grunt,Babel,Mocha等。如果您编写了一个Gulp插件,您希望该插件与用户的项目正在使用的Gulp一起工作,而不是与您自己的私有版本Gulp一起工作。

匿名用户

我建议你先把这篇文章再读一遍。这有点令人困惑,但是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

在这种情况下,一个包可能有多个版本,这会导致一些问题。对等依赖允许npm开发人员确保用户拥有特定的模块(在根文件夹中)。但是您的观点是正确的,即描述包的一个特定版本会导致使用其他版本的其他包出现问题。正如文章所述,这个问题与npm开发人员有关

有一条建议:与常规依赖项不同的是,对等依赖项的要求应该是宽松的。不应将对等项依赖锁定到特定的修补程序版本。

因此,开发人员应该遵循semver来定义对等依赖关系。您应该在github..上为grunt-steroids包打开一个问题。

匿名用户

用最简单的示例进行了解释:

{
  "name": "myPackage",
  "dependencies": {
    "foo": "^4.0.0",
    "react": "^15.0.0"
  }
}


{
  "name": "foo"
  "peerDependencies": {
    "react": "^16.0.0"
  }
}

在myPackage中运行npm安装将引发错误,因为它试图安装React版本,后者仅与React版本兼容。

未安装对等依赖项。