2515

该文档非常糟糕地回答了我的问题。我不明白那些解释。有人能用更简单的话说吗?如果很难选择简单的单词,也许有例子?

EDIT还添加了peerDependencies,这是密切相关的,可能会引起混淆。

4

16 回答 16

2851

重要行为差异总结:

  • dependencies都安装在:

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

    • 也安装在npm install包含 的目录上package.json,除非您通过--production标志(去投票 Gayan Charith 的答案)。
    • 没有安装在npm install "$package"任何其他目录上,除非你给它--dev选项。
    • 不会传递安装。
  • peerDependencies

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

    • dependencies传递安装:如果 A 需要 B,B 需要 C,则安装 C,否则,B 无法工作,A 也不会。

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

此处未讨论的相关选项:

开发依赖

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依赖项中。

例如,如果dependency1两者dependency2都依赖dependency3于不同的版本,项目树将如下所示:

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

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

  • 主机需要插件
  • 插件提供主机期望找到的标准接口
  • 只有主机会被用户直接调用,所以它必须只有一个版本。

例如,如果dependency1dependency2peer 依赖dependency3,项目树将如下所示:

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

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

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

对等依赖的一个典型例子是 Grunt、主机和它的插件。

例如,在像https://github.com/gruntjs/grunt-contrib-uglify这样的 Grunt 插件上,您将看到:

  • grunt是一个peer-dependency
  • 唯一require('grunt')的是tests/:它实际上并没有被程序使用。

然后,当用户使用插件时,他会Gruntfile通过添加grunt.loadNpmTasks('grunt-contrib-uglify')一行来隐式地要求插件,但这grunt是用户将直接调用的。

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

手动的

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

关键线是:

这些东西将在从包的根目录执行 npm link 或 npm install 时安装,并且可以像任何其他 npm 配置参数一样进行管理。有关该主题的更多信息,请参阅 npm-config(7)。

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

Default: false
Type: Boolean

Install dev-dependencies along with packages.
于 2014-02-25T04:25:31.627 回答
589

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

于 2015-07-05T10:06:35.143 回答
141

例如,mocha 通常是一个 devDependency,因为在生产中不需要测试,而 express 是一个依赖项。

于 2013-09-18T18:39:54.463 回答
122

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

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

peerDependencies
项目在父项目中挂钩或修改的依赖项,通常是其他库或工具的插件。它只是为了检查,确保父项目(将依赖于您的项目的项目)依赖于您挂钩的项目。因此,如果您制作了一个向库 B 添加功能的插件 C,那么制作项目 A 的人将需要依赖于 B,如果他们依赖于 C。
它们没有安装(除非 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

于 2017-09-05T17:27:44.723 回答
76

要将包保存到package.json作为开发依赖项:

npm install "$package" --save-dev

当您运行npm install时,它将同时安装devDependenciesdependencies. 为避免安装devDependencies运行:

npm install --production
于 2016-01-08T06:41:47.610 回答
44

有一些模块和包仅用于开发,而在生产中不需要。就像它在文档中所说的那样:

如果有人计划在他们的程序中下载和使用您的模块,那么他们可能不希望或不需要下载和构建您使用的外部测试或文档框架。在这种情况下,最好在 devDependencies 哈希中列出这些附加项。

于 2013-09-18T14:59:46.953 回答
23

peerDependencies直到我从关于上面提到的 Ciro主题的博客文章中阅读了这个片段之前,对我来说并不是很有意义:

[插件] 需要的是一种表达插件和它们的宿主包之间的“依赖关系”的方式。某种说法,“我只在插入我的主机包的 1.2.x 版本时工作,所以如果你安装我,请确保它与兼容的主机一起使用。” 我们称这种关系为对等依赖。

该插件确实需要特定版本的主机...

peerDependencies用于插件,需要“主机”库来执行其功能的库,但可能是在最新版本的主机发布之前编写的。

也就是说,如果我写信PluginX v1HostLibraryX v3离开,则无法保证(甚至)发布PluginX v1时会起作用。HostLibraryX v4HostLibraryX v3.0.1

...但插件不依赖于主机...

从插件的角度来看,它只是向宿主库添加了功能。我并不真正“需要”主机向插件添加依赖项,并且插件通常并不真正依赖于它们的主机。如果您没有主机,则该插件不会无害地执行任何操作。

这意味着dependencies对于插件来说并不是真正的正确概念。

更糟糕的是,如果我的主机被视为依赖项,我们最终会遇到同一篇博客文章提到的这种情况(稍作编辑以使用此答案的主机和插件组成):

但是现在,[如果我们将 HostLibraryX 的当代版本视为 PluginX 的依赖项,] 运行npm install会导致意外的依赖关系图

├── HostLibraryX@4.0.0
└─┬ PluginX@1.0.0
  └── HostLibraryX@3.0.0

我会将插件使用与主应用程序不同的 [HostLibraryX] API 带来的细微故障留给您想象。

...而且主机显然不依赖于插件...

...这就是插件的重点。现在,如果主机足够好,可以包含所有插件的依赖信息,那将解决问题,但这也会引入一个巨大的新文化问题:插件管理!

插件的全部意义在于它们可以匿名配对。在一个完美的世界里,让主人管理它们会很整洁,但我们不需要图书馆放猫。

如果我们不是等级依赖的,也许我们是内部依赖的同伴......

相反,我们有成为同行的概念。主机和插件都不在对方的依赖桶中。两者都生活在依赖图的同一级别。


...但这不是一种可自动化的关系。<<< 钱球!!!

如果我期望(即PluginX v1一个 peerDependency of)的同级,我会这么说。如果您已自动升级到最新版本(请注意是版本4已安装,您需要知道,对吗?HostLibraryX v3HostLibraryX v4Plugin v1

npm无法为我处理这种情况——

“嘿,我看到你在使用PluginX v1!我HostLibraryX从v4自动降级到v3,kk?”

... 或者...

“嘿,我看到你在使用PluginX v1.应该是HostLibraryX v3,你在上次更新期间把它留在了尘土中。为了安全起见,我会自动卸载Plugin v1!!1!

不怎么样,npm?!

所以 npm 没有。它会提醒您注意这种情况,并让您确定是否HostLibraryX v4适合Plugin v1.


结尾

插件中的良好peerDependency管理将使这个概念在实践中更直观地工作。从博客文章中,再次...

一条建议:与常规依赖不同,对等依赖要求应该宽松。您不应该将您的对等依赖项锁定到特定的补丁版本。如果一个 Chai 插件对等依赖于 Chai 1.4.1,而另一个依赖于 Chai 1.5.0,那真的很烦人,仅仅是因为作者很懒,没有花时间弄清楚他们是 Chai 的实际最低版本兼容。

于 2018-08-29T14:47:27.803 回答
21

一个让我更清楚的简单解释是:

当您部署应用程序时,需要安装依赖项中的模块,否则您的应用程序将无法运行。devDependencies 中的模块不需要安装在生产服务器上,因为您不是在该机器上开发。 关联

于 2017-09-29T15:36:08.237 回答
18

我想在答案中添加我对这些依赖项解释的看法

  • dependencies用于在您的代码库中直接使用,通常在生产代码中结束的东西,或代码块
  • devDependencies用于构建过程,帮助您管理最终代码的工具,第三方测试模块,(例如 webpack 的东西)
于 2018-02-16T11:40:18.690 回答
16

我找到了一个简单的解释。

简短的回答:

依赖项 “......是您的项目真正需要能够在生产中工作的那些。”

devDependencies “......是您在开发过程中需要的那些。”

peerDependencies “如果你想创建和发布自己的库,以便它可以用作依赖项”

这篇文章中的更多细节: https ://code-trotter.com/web/dependencies-vs-devdependencies-vs-peerdependencies

于 2020-02-04T14:12:22.840 回答
12

简而言之

  1. 依赖项- npm install <package> --save-prod在生产环境中安装应用程序所需的软件包。

  2. DevDependencies - npm install <package> --save-dev安装本地开发和测试所需的包

  3. 只需键入npm install即可安装 package.json 中提到的所有包

因此,如果您在本地计算机上工作,只需键入npm install并继续 :)

于 2019-06-07T05:27:25.623 回答
6

依赖与开发依赖

开发依赖项是仅在开发期间需要的模块,而在运行时需要依赖项。如果您正在部署应用程序,则必须安装依赖项,否则您的应用程序将无法运行。您从代码中调用的使程序能够运行的库可以被视为依赖项。

例如-反应,反应-dom

开发依赖模块不需要安装在生产服务器中,因为您不会在那台机器上进行开发。将代码转换为 javascript 的编译器、测试框架和文档生成器可以被视为开发依赖,因为它们仅在开发期间需要。

例如- ESLint 、 Babel 、 webpack

@供参考,

mod-a
  dev-dependents:
    - mod-b
  dependents:
    - mod-c

mod-d
  dev-dependents:
    - mod-e
  dependents:
    - mod-a

----

npm install mod-d

installed modules:
  - mod-d
  - mod-a
  - mod-c

----

checkout the mod-d code repository

npm install

installed modules:
  - mod-a
  - mod-c
  - mod-e

如果您要发布到 npm,那么为正确的模块使用正确的标志很重要。如果它是你的 npm 模块需要运行的东西,那么使用“--save”标志将模块保存为依赖项。如果它是您的模块不需要运行但需要进行测试的东西,则使用“--save-dev”标志。

# For dependent modules
npm install dependent-module --save

# For dev-dependent modules
npm install development-module --save-dev
于 2019-07-29T09:50:34.423 回答
1

依赖项

这些是你的包需要运行的包,所以它们会在人们运行时安装

 npm install PACKAGE-NAME

例如,如果您在项目中使用了 jQuery。如果有人没有安装 jQuery,那么它将无法工作。要保存为依赖项,请使用

 npm install --save

开发依赖

这些是您在开发中使用的依赖项,但在人们使用它时不需要,因此当人们运行时npm install,它不会安装它们,因为它们不是必需的。比如你mocha用来测试,人家不需要mocha跑,所以npm install不安装。要另存为开发依赖项,请使用

npm install PACKAGE --save-dev

对等依赖

如果您想创建和发布自己的库以便将其用作依赖项,则可以使用这些。例如,如果您希望您的包在另一个项目中用作依赖项,那么当有人安装将您的项目作为依赖项的项目时,也会安装这些包。大多数情况下,您不会使用对等依赖项。

于 2020-10-12T22:24:38.593 回答
0

尝试分发 npm 包时,应避免使用dependencies. 相反,您需要考虑将其添加到peerDependencies.

更新

大多数时候,依赖关系只是一堆描述你的生态系统的库。除非,您确实使用的是特定版本的库,否则您应该让用户选择是否安装该库以及通过将其添加到 peerDependencies 中来选择哪个版本。

于 2018-07-06T12:47:33.163 回答
0
于 2022-02-12T12:49:13.207 回答
0

需要依赖项才能运行,devDependencies 仅用于开发

于 2022-02-17T07:02:41.473 回答