该文档非常糟糕地回答了我的问题。我不明白那些解释。有人能用更简单的话说吗?如果很难选择简单的单词,也许有例子?
EDIT还添加了peerDependencies
,这是密切相关的,可能会引起混淆。
该文档非常糟糕地回答了我的问题。我不明白那些解释。有人能用更简单的话说吗?如果很难选择简单的单词,也许有例子?
EDIT还添加了peerDependencies
,这是密切相关的,可能会引起混淆。
重要行为差异总结:
dependencies
都安装在:
npm install
从包含package.json
npm install $package
在任何其他目录上npm install
包含 的目录上package.json
,除非您通过--production
标志(去投票 Gayan Charith 的答案)。npm install "$package"
任何其他目录上,除非你给它--dev
选项。npm install
,您必须自己手动解决依赖关系。运行时,如果缺少依赖项,则会出现错误(@nextgentech提到)这很好地解释了它:https ://flaviocopes.com/npm-peer-dependencies/传递性(Ben Hutchison提到):
dependencies
传递安装:如果 A 需要 B,B 需要 C,则安装 C,否则,B 无法工作,A 也不会。
devDependencies
没有传递安装。例如,我们不需要测试 B 来测试 A,因此可以省略 B 的测试依赖项。
此处未讨论的相关选项:
bundledDependencies
在以下问题上进行了讨论:bundledDependencies 优于 npm 中的正常依赖项的优势optionalDependencies
(艾丹·费尔德曼提到)dependencies
需要运行,devDependencies
仅用于开发,例如:单元测试、CoffeeScript 到 JavaScript 的转译、缩小、...
如果你要开发一个包,你下载它(例如通过git clone
),进入它的根目录,其中包含package.json
,然后运行:
npm install
既然你有实际的源代码,很明显你想开发它,所以默认情况下,也安装了dependencies
(因为你当然必须运行开发)和devDependency
依赖项。
但是,如果您只是想要安装软件包以使用它的最终用户,您可以从任何目录执行:
npm install "$package"
在这种情况下,您通常不需要开发依赖项,因此您只需获取使用包所需的内容:dependencies
.
如果您真的想在这种情况下安装开发包,您可以将dev
配置选项设置为true
,可能从命令行设置为:
npm install "$package" --dev
该选项是false
默认的,因为这是一种不太常见的情况。
(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/
但是,插件是通常不需要其他包的包,在此上下文中称为主机。反而:
例如,如果dependency1
和dependency2
peer 依赖dependency3
,项目树将如下所示:
root/node_modules/
|
+- dependency1/
|
+- dependency2/
|
+- dependency3 v1.0/
即使您从未dependency3
在package.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.
如果您不想安装 devDependencies,您可以使用npm install --production
例如,mocha 通常是一个 devDependency,因为在生产中不需要测试,而 express 是一个依赖项。
依赖
项 项目需要运行的依赖项,例如提供从代码调用的函数的库。
它们是传递安装的(如果 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
要将包保存到package.json作为开发依赖项:
npm install "$package" --save-dev
当您运行npm install
时,它将同时安装devDependencies
和dependencies
. 为避免安装devDependencies
运行:
npm install --production
有一些模块和包仅用于开发,而在生产中不需要。就像它在文档中所说的那样:
如果有人计划在他们的程序中下载和使用您的模块,那么他们可能不希望或不需要下载和构建您使用的外部测试或文档框架。在这种情况下,最好在 devDependencies 哈希中列出这些附加项。
peerDependencies
直到我从关于上面提到的 Ciro主题的博客文章中阅读了这个片段之前,对我来说并不是很有意义:
[插件] 需要的是一种表达插件和它们的宿主包之间的“依赖关系”的方式。某种说法,“我只在插入我的主机包的 1.2.x 版本时工作,所以如果你安装我,请确保它与兼容的主机一起使用。” 我们称这种关系为对等依赖。
peerDependencies
用于插件,需要“主机”库来执行其功能的库,但可能是在最新版本的主机发布之前编写的。
也就是说,如果我写信PluginX v1
并HostLibraryX v3
离开,则无法保证(甚至)发布PluginX v1
时会起作用。HostLibraryX v4
HostLibraryX 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 v3
HostLibraryX v4
Plugin 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 的实际最低版本兼容。
一个让我更清楚的简单解释是:
当您部署应用程序时,需要安装依赖项中的模块,否则您的应用程序将无法运行。devDependencies 中的模块不需要安装在生产服务器上,因为您不是在该机器上开发。 关联
我想在答案中添加我对这些依赖项解释的看法
dependencies
用于在您的代码库中直接使用,通常在生产代码中结束的东西,或代码块devDependencies
用于构建过程,帮助您管理最终代码的工具,第三方测试模块,(例如 webpack 的东西)我找到了一个简单的解释。
简短的回答:
依赖项 “......是您的项目真正需要能够在生产中工作的那些。”
devDependencies “......是您在开发过程中需要的那些。”
peerDependencies “如果你想创建和发布自己的库,以便它可以用作依赖项”
这篇文章中的更多细节: https ://code-trotter.com/web/dependencies-vs-devdependencies-vs-peerdependencies
简而言之
依赖项- npm install <package> --save-prod
在生产环境中安装应用程序所需的软件包。
DevDependencies - npm install <package> --save-dev
安装本地开发和测试所需的包
只需键入npm install
即可安装 package.json 中提到的所有包
因此,如果您在本地计算机上工作,只需键入npm install
并继续 :)
依赖与开发依赖
开发依赖项是仅在开发期间需要的模块,而在运行时需要依赖项。如果您正在部署应用程序,则必须安装依赖项,否则您的应用程序将无法运行。您从代码中调用的使程序能够运行的库可以被视为依赖项。
例如-反应,反应-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
这些是你的包需要运行的包,所以它们会在人们运行时安装
npm install PACKAGE-NAME
例如,如果您在项目中使用了 jQuery。如果有人没有安装 jQuery,那么它将无法工作。要保存为依赖项,请使用
npm install --save
这些是您在开发中使用的依赖项,但在人们使用它时不需要,因此当人们运行时npm install
,它不会安装它们,因为它们不是必需的。比如你mocha
用来测试,人家不需要mocha
跑,所以npm install
不安装。要另存为开发依赖项,请使用
npm install PACKAGE --save-dev
如果您想创建和发布自己的库以便将其用作依赖项,则可以使用这些。例如,如果您希望您的包在另一个项目中用作依赖项,那么当有人安装将您的项目作为依赖项的项目时,也会安装这些包。大多数情况下,您不会使用对等依赖项。
尝试分发 npm 包时,应避免使用dependencies
. 相反,您需要考虑将其添加到peerDependencies
.
大多数时候,依赖关系只是一堆描述你的生态系统的库。除非,您确实使用的是特定版本的库,否则您应该让用户选择是否安装该库以及通过将其添加到 peerDependencies 中来选择哪个版本。
需要依赖项才能运行,devDependencies 仅用于开发