开发者问题收集

NPM package.json 文件中的 dependency、devDependencies 和 peerDependencies 有什么区别?

2013-09-18
1012527

此文档 对我的问题回答得非常糟糕。我不明白那些解释。有人能用更简单的语言说一下吗?如果很难选择简单的词语,也许可以举例说明?

还添加了 peerDependencies ,它密切相关并且可能会引起混淆。

3个回答

重要行为差异摘要:

  • dependencies 安装在两者上:

    • npm install 来自包含 package.json 的目录
    • npm install $package 在任何其他目录上
  • devDependencies 是:

    • 也安装在包含 package.json 的目录中的 npm install 上,除非您传递 --production 标志(为 Gayan Charith 的答案 点赞),或者设置了 NODE_ENV=production 环境变量
    • 不会安装在任何其他目录中的 npm install "$package" 上,除非您为其提供 --dev 选项。
    • 不会间接安装。
  • peerDependencies

    • 3.0 之前:如果缺失,则始终安装,如果不同依赖项使用多个不兼容版本的依赖项,则会引发错误。
    • 预计从 3.0 开始 (未经测试):如果 npm install 上缺少依赖项,则会发出警告,您必须手动解决依赖关系。运行时,如果缺少依赖项,则会收到错误(由 @nextgentech 提及)这很好地解释了这一点: https://flaviocopes.com/npm-peer-dependencies/
    • 在版本 7 中,除非存在无法自动解决的上游依赖项冲突,否则将自动安装 peerDependencies
  • 传递性(由 Ben Hutchison ):

    • 依赖项 是可传递安装的:如果 A 需要 B,而 B 需要 C,则 C 会被安装,否则,B 无法工作,A 也无法工作。

    • devDependencies 不是可传递安装的。例如我们不需要测试 B 来测试 A,因此可以省略 B 的测试依赖项。

此处未讨论的相关选项:

devDependencies

运行需要 dependencies ,开发只需要 devDependencies ,例如:单元测试、CoffeeScript 到 JavaScript 的转译、压缩……

如果您要开发一个包,您可以下载它(例如通过 git clone ),转到包含 package.json 的根目录,然后运行:

npm install

由于您拥有实际源代码,因此很明显您想要开发它,因此默认情况下,还会安装 dependencies (因为您必须运行才能开发)和 devDependency 依赖项。

但是,如果您只是一个只想安装包来使用它的最终用户,您可以从任何目录执行此操作:

npm install "$package"

在该目录中在这种情况下,您通常不需要开发依赖项,因此您只需获取使用包所需的内容: dependencies

如果您确实想在这种情况下安装开发包,可以将 dev 配置选项设置为 true ,可能从命令行执行如下操作:

npm install "$package" --dev

默认情况下,该选项为 false ,因为这种情况不太常见。

peerDependencies

(在 3.0 之前测试过)

来源: https://nodejs.org/en/blog/npm/peer-dependencies/

使用常规依赖项,您可以拥有依赖项的多个版本:它只是安装在 node_modules 的依赖项。

例如,如果 dependency1dependency2 都依赖于不同版本的 dependency3 ,则项目树将如下所示:

root/node_modules/
                 |
                 +- dependency1/node_modules/
                 |                          |
                 |                          +- dependency3 v1.0/
                 |
                 |
                 +- dependency2/node_modules/
                                            |
                                            +- dependency3 v2.0/

但是,插件是通常不需要其他包的包,在此上下文中称为 主机 。相反:

  • 插件是 主机 所需的
  • 插件提供主机希望找到的标准接口
  • 只有主机才会被用户直接调用,因此必须有一个版本。

例如如果 dependency1dependency2 对等依赖于 dependency3 ,则项目树将如下所示:

root/node_modules/
                 |
                 +- dependency1/
                 |
                 +- dependency2/
                 |
                 +- dependency3 v1.0/

即使您从未在 package.json 文件中提及 dependency3 ,也会发生这种情况。

我认为这是 控制反转 设计模式的一个实例。

对等依赖的一个典型示例是 Grunt、主机及其插件。

例如,在 Grunt 插件(如 https://github.com/gruntjs/grunt-contrib-uglify )上,您将看到:

  • grunt对等依赖
  • 唯一的 require('grunt') 位于 tests/ 下:程序实际上并未使用它。

然后,当用户使用插件时,他将通过添加 grunt.loadNpmTasks('grunt-contrib-uglify') 行从 Gruntfile 隐式地请求该插件,但用户将直接调用 grunt

如果每个插件都需要不同的 Grunt 版本,那么这将不起作用。

手册

我认为文档很好地回答了这个问题,也许你只是对节点/其他包管理器不够熟悉。我可能只是因为我对 Ruby 捆绑器了解一点才理解它。

关键行是:

These things will be installed when doing npm link or npm install from the root of a package and can be managed like any other npm configuration parameter. See npm-config(7) for more on the topic.

然后在 npm-config(7) 下找到 dev

Default: false
Type: Boolean

Install dev-dependencies along with packages.
Ciro Santilli OurBigBook.com
2014-02-25

如果您不想安装 devDependencies,您可以使用 npm install --production

Gayan Charith
2015-07-05

依赖项
您的项目需要运行的依赖项,例如提供您从代码中调用的函数的库。
它们是可传递安装的(如果 A 依赖于 B,而 B 又依赖于 C,则 A 上的 npm install 将安装 B 和 C)。
示例:lodash:您的项目调用了一些 lodash 函数。

devDependencies
您仅在开发或发布期间需要的依赖项,例如获取您的代码并将其编译为 javascript、测试框架或文档生成器的编译器。
它们不是可传递安装的(如果 A 依赖于 B,而 B 依赖于 C,则 A 上的 npm install 将仅安装 B)。
示例:grunt:您的项目使用 grunt 来构建自身。

peerDependencies
您的项目在父项目中挂接或修改的依赖项,通常是其他库或工具的插件。它只是用来检查,确保父项目(将依赖于您的项目的项目)依赖于您挂接的项目。因此,如果您制作了一个插件 C,为库 B 添加了功能,那么制作项目 A 的人如果对 C 有依赖,就需要对 B 有依赖。
它们不会安装(除非 npm < 3),只会检查它们。
示例:grunt:您的项目为 grunt 添加了功能,只能在使用 grunt 的项目上使用。

此文档很好地解释了对等依赖关系: https://nodejs.org/en/blog/npm/peer-dependencies/

此外,npm 文档随着时间的推移不断改进,现在对不同类型的依赖关系有了更好的解释: https://github.com/npm/cli/blob/latest/docs/content/configuring-npm/package-json.md#devdependencies

qwertzguy
2017-09-05