This documentation 对我的问题的回答很差。我不明白那些解释。有人能用更简单的话说吗?如果很难选择简单的单词,也许有例子?
EDIT 还添加了 peerDependencies
,它密切相关,可能会引起混淆。
optionalDependencies
。
重要行为差异总结:
依赖项安装在两者上: npm install 从包含 package.json 的目录 npm install $package 在任何其他目录
从包含 package.json 的目录中安装 npm
npm install $package 在任何其他目录上
devDependencies 是:也安装在 npm install 包含 package.json 的目录上,除非你通过 --production 标志(去投票 Gayan Charith 的答案),或者如果 NODE_ENV=production 环境变量设置为 not installed on npm install "$包”在任何其他目录上,除非你给它 --dev 选项。不会传递安装。
也安装在 npm install 包含 package.json 的目录上,除非您通过 --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 除非上游依赖项冲突存在无法自动解决
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 的测试依赖项。
依赖项是传递安装的:如果 A 需要 B,而 B 需要 C,则安装 C,否则,B 不能工作,A 也不能工作。
devDependencies 不会传递安装。例如,我们不需要测试 B 来测试 A,因此可以省略 B 的测试依赖项。
此处未讨论的相关选项:
bundledDependencies 在以下问题上进行了讨论:与 npm 中的正常依赖关系相比 bundledDependencies 的优势
optionalDependencies(由 Aidan Feldman 提到)
开发依赖
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/
但是,插件是通常不需要其他包的包,在此上下文中称为主机。反而:
主机需要插件
插件提供主机期望找到的标准接口
只有主机会被用户直接调用,所以它必须只有一个版本。
例如,如果 dependency1
和 dependency2
对等点依赖于 dependency3
,则项目树将如下所示:
root/node_modules/
|
+- dependency1/
|
+- dependency2/
|
+- dependency3 v1.0/
即使您从未在 package.json
文件中提及 dependency3
,也会发生这种情况。
我认为这是 Inversion of Control 设计模式的一个实例。
对等依赖的一个典型例子是 Grunt、主机和它的插件。
例如,在像 https://github.com/gruntjs/grunt-contrib-uglify 这样的 Grunt 插件上,您会看到:
grunt 是对等依赖
唯一的 require('grunt') 正在测试中/:程序实际上并未使用它。
然后,当用户将使用插件时,他将通过添加 grunt.loadNpmTasks('grunt-contrib-uglify')
行隐式地从 Gruntfile
中要求插件,但用户将直接调用 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
--save
选项。如果您执行“npm install my-package”,它会将 my-package 作为依赖项添加到您的 package.json
文件中。
--save
选项,而实际上不保存您添加依赖项的事实几乎没有意义。
例如,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 的人如果依赖于 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
要将包保存到 package.json 作为开发依赖项:
npm install "$package" --save-dev
当您运行 npm install
时,它将同时安装 devDependencies
和 dependencies
。为避免安装 devDependencies
运行:
npm install --production
有一些模块和包仅用于开发,而在生产中不需要。就像它在 documentation 中所说的那样:
如果有人计划在他们的程序中下载和使用您的模块,那么他们可能不想或不需要下载和构建您使用的外部测试或文档框架。在这种情况下,最好在 devDependencies 哈希中列出这些附加项。
在我阅读了 a blog post 关于主题 Ciro mentioned above 的这段片段之前,peerDependencies
对我来说并不是很有意义:
[插件] 需要的是一种表达插件及其主机包之间“依赖关系”的方式。某种说法,“我只在插入我的主机包的 1.2.x 版本时工作,所以如果你安装我,请确保它与兼容的主机一起使用。”我们称这种关系为对等依赖。
该插件确实需要特定版本的主机...
peerDependencies
用于插件、需要“主机”库来执行其功能的库,但可能是在发布最新版本的主机之前编写的。
也就是说,如果我为 HostLibraryX v3
写 PluginX v1
并走开,则无法保证 PluginX v1
在 HostLibraryX v4
(甚至 HostLibraryX v3.0.1
)发布时会起作用。
...但插件不依赖于主机...
从插件的角度来看,它只是向宿主库添加了功能。我并不真正“需要”主机向插件添加依赖项,并且插件通常并不真正依赖于它们的主机。如果您没有主机,则该插件不会无害地执行任何操作。
这意味着 dependencies
并不是真正适合插件的概念。
更糟糕的是,如果我的主机被视为依赖项,我们最终会遇到这种情况 the same blog post mentions (稍作编辑以使用此答案由主机和插件组成):
但是现在,[如果我们将 HostLibraryX 的现代版本视为 PluginX 的依赖项,] 运行 npm install 会导致意外的依赖关系图 ├── HostLibraryX@4.0.0 └─┬ PluginX@1.0.0 └── HostLibraryX@ 3.0.0 我将把插件使用与主应用程序不同的 [HostLibraryX] API 带来的细微故障留给您想象。
...而且主机显然不依赖于插件...
...这就是插件的重点。现在,如果主机足够好,可以包含所有插件的依赖信息,那将解决问题,但这也会引入一个巨大的新文化问题:插件管理!
插件的全部意义在于它们可以匿名配对。在一个完美的世界里,让主人管理它们会很整洁,但我们不需要图书馆放猫。
如果我们不是等级依赖的,也许我们是内部依赖的同伴......
相反,我们有成为同行的概念。主机和插件都不在对方的依赖桶中。两者都生活在依赖图的同一级别。
...但这不是一种可自动化的关系。 <<< 钱球!!!
如果我是 PluginX v1
并且 期望 是 HostLibraryX v3
的对等点(即 具有 的 peerDependency),我会这样说。如果您已自动升级到最新的 HostLibraryX v4
(请注意是版本 4)并且已安装 Plugin v1
,您需要知道,对吧?
npm
无法为我处理这种情况 --
“嘿,我看到你在使用 PluginX v1!我正在自动将 HostLibraryX 从 v4 降级到 v3,kk?”
... 或者...
“嘿,我看到您正在使用 PluginX v1。这需要 HostLibraryX v3,您在上次更新期间将其留在了尘埃中。为了安全起见,我将自动卸载 Plugin v1!!1!
不怎么样,npm?!
所以 npm 没有。它会提醒您注意这种情况,并让您确定 HostLibraryX v4
是否适合 Plugin v1
。
结尾
插件中良好的 peerDependency
管理将使这个概念在实践中更直观地工作。从the blog post,再次...
一条建议:与常规依赖不同,对等依赖要求应该宽松。您不应该将您的对等依赖项锁定到特定的补丁版本。如果一个 Chai 插件对等依赖于 Chai 1.4.1,而另一个依赖于 Chai 1.5.0,那真的很烦人,仅仅是因为作者很懒,没有花时间弄清楚他们是 Chai 的实际最低版本兼容。
一个让我更清楚的简单解释是:
当您部署应用程序时,需要安装依赖项中的模块,否则您的应用程序将无法运行。 devDependencies 中的模块不需要安装在生产服务器上,因为您不是在该机器上开发。 link
vendor.js
中,如果已编译的代码提交到 repo 中,我们所有的 deps 都应该是 dev deps?它应该被提交,否则很奇怪你必须编译模块,而不仅仅是安装它(并且测试也在这里的某个地方,因为子模块的任何变化都可能导致回归)......
webpack -p
我的意思是。请回答我的问题。
我想在答案中添加我对这些依赖项解释的看法
依赖项用于在您的代码库中直接使用,通常最终出现在生产代码中的东西,或代码块
devDependencies 用于构建过程,帮助您管理最终代码的工具,第三方测试模块,(例如 webpack 的东西)
我找到了一个简单的解释。
简短的回答:
依赖项“......是您的项目真正需要能够在生产中工作的那些。”
devDependencies “......是您在开发过程中需要的那些。”
peerDependencies “如果你想创建和发布自己的库,以便它可以用作依赖项”
这篇文章中的更多详细信息:https://code-trotter.com/web/dependencies-vs-devdependencies-vs-peerdependencies
peerDependencies
对我来说。
简而言之
依赖项 - npm install
因此,如果您在本地计算机上工作,只需键入 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
对等依赖
如果您想创建和发布自己的库以便将其用作依赖项,则可以使用这些。例如,如果您希望您的包在另一个项目中用作依赖项,那么当有人安装将您的项目作为依赖项的项目时,也会安装这些包。大多数情况下,您不会使用对等依赖项。
依赖项:您的项目/包需要在生产中工作的包。
devDependencies:您的项目/包在开发时需要工作但在生产中不需要的包(例如:测试包)
peerDependencies:您的项目/包需要协同工作(与它们“合作”)或作为基础的包,主要在您开发插件/组件时有用,以便了解您的插件使用哪个版本的“主”包/component 应该可以使用(例如:React 16)
尝试分发 npm 包时,应避免使用 dependencies
。相反,您需要考虑将其添加到 peerDependencies
中。
更新
大多数时候,依赖关系只是一堆描述你的生态系统的库。除非,您真的使用特定版本的库,否则您应该让用户选择是否安装该库以及通过将其添加到 peerDependencies 中来选择哪个版本。
dependencies
?
这两者之间的区别在于 devDependencies 是仅在开发期间需要的模块,而依赖项是在运行时也需要的模块。
要在安装时将依赖项保存为 devDependency,我们需要执行 #npm install --save-dev,而不仅仅是 #npm install --save
安装我喜欢使用的 devDependency 的一个很好的简写是#npm i -D。保存常规依赖项的简写是 -S 而不是 -D。
运行时需要的一些很好的依赖关系示例包括 React、Redux、Express 和 Axios。
何时安装 devDependencies 的一些很好的例子是 Nodemon、Babel、ESLint 和测试框架,如 Chai、Mocha、Enzyme 等……
需要依赖项才能运行,devDependencies 仅用于开发
使用 Webpack 捆绑前端应用程序时,依赖项和 devDependencies 之间的区别不是很清楚。对于最终的捆绑包,放置依赖项的位置无关紧要(但对于其他工具可能很重要)。这就是文档看起来令人困惑的原因。
我在这里找到了解释:Do "dependencies" and "devDependencies" matter when using Webpack?
不定期副业成功案例分享
npm install package
是一个命令,您将使用它来安装所有不是开发依赖项的软件包,而不是我现在认为您的意思,即“安装名为 [package] 的软件包”,这就是我的方式在阅读本文之前认为它有效。如果我是你,我会编辑说 [package-name] 这清楚地表明你的意思是“插入名称-here”。peerDependencies
行为。来自 blog.npmjs.org/post/110924823920/npm-weekly-5:“我们将不再自动下载对等依赖项。相反,如果尚未安装对等依赖项,我们会警告您。这需要您手动解决 peerDependency 冲突,但在很长一段时间内运行它应该可以减少你最终遇到包依赖项的棘手问题。”npm install
,您将获得 B 和 C,但不会获得 D。NODE_ENV
设置为production
时,不会安装devDependencies
。