node.js - 为什么在 npm 中为插件使用对等依赖项?

标签 node.js npm package-managers

例如,为什么 Grunt 插件将其对 grunt 的依赖定义为“peer dependencies”?

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

此处描述了对等依赖关系:https://nodejs.org/en/blog/npm/peer-dependencies/

但我真的不明白。

示例

我目前正在使用 AppGyver Steroids,它使用 Grunt 任务将我的源文件构建到/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"
  },

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

没有安装“devDependencies”,我确定它是由 npm 控制的,检测我只是在尝试使用 grunt-steroids,而不是开发就可以了。

但是我们有“peerDependencies”。

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

最佳答案

TL;DR: peerDependencies 用于暴露给消费代码(并期望被消费代码使用)的依赖项,而不是 "private" 未公开的依赖项,只是一个实现细节。

对等依赖解决的问题

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

但在以下情况下会出现问题:

  • 您的项目和您正在使用的某个模块都依赖于另一个模块。
  • 三个模块必须相互通信。

在示例中

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

但是现在如果 JacksModule 以某种方式暴露它对 JillsModule 的依赖会怎么样。例如,它接受 JillsClass 的实例...当我们使用库的版本 2.0 创建一个 new JillsClass 并将其传递时会发生什么jacksFunction?所有的 hell 都会崩溃!像 jillsObject instanceof JillsClass 这样简单的东西会突然返回 false 因为 jillsObject 实际上是 another JillsClass 的一个实例2.0 版本。

对等依赖如何解决这个问题

他们告诉 npm

I need this package, but I need the version that is part of the project, not some version private to my module.

当 npm 发现你的包被安装到一个没有有该依赖的项目中,或者有一个不兼容的版本的项目中,它会警告用户在安装过程中。

什么时候应该使用对等依赖项?

  • 当您构建一个供其他项目使用的库时,
  • 这个库正在使用其他库,
  • 您希望/需要用户也使用其他库

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

关于node.js - 为什么在 npm 中为插件使用对等依赖项?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26737819/

相关文章:

c# - 在源代码和预编译二进制文件之间切换

emacs - 不要截断 emacs 包列表中的包名称。

javascript - Bookshelf.js 设置属性不在数据库中

node.js - 由于校验和不匹配,nvm 安装 nodejs 失败

node.js - npm 错误!无法读取未定义的属性 'pause' --Bluemix

node.js - NPM 问题 : Node-pre-gyp. 使用 node-pre-gyp https 下载请求

javascript - '引用错误 : jest is not defined' when running unit test

javascript - 是否可以使用 Node.js 创建 XLS excel 文件并控制单元格类型?

angular - 执行 "ng serve"或 "npm start"命令浏览器未自动打开

package-managers - 如果软件自行更新并尝试再次通过 choco 更新,对巧克力有什么副作用?