这份文档回答了我的问题,但解释得不够清楚。有没有人能用更简单的话来说一下?如果难以选择简单的词语,可以举例说明吗?
另外,我还添加了peerDependencies
,这个也与之密切相关,可能会引起混淆。
这份文档回答了我的问题,但解释得不够清楚。有没有人能用更简单的话来说一下?如果难以选择简单的词语,可以举例说明吗?
另外,我还添加了peerDependencies
,这个也与之密切相关,可能会引起混淆。
dependencies
需要安装在以下两种情况下:
package.json
的目录中运行npm install
npm install $package
package.json
的目录中运行npm install
时,除非您传递了--production
标志(请为Gayan Charith's answer投票),或者设置了NODE_ENV=production
环境变量,否则也会被安装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
,在以下问题中进行了讨论:npm中捆绑依赖项的优势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
,因为这是一个较少见的情况。
(在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
,这也会发生。grunt
是peer-dependency
require('grunt')
在tests/
下:它实际上并未被程序使用。grunt.loadNpmTasks('grunt-contrib-uglify')
行来隐式地从Gruntfile
中要求插件,但用户将直接调用grunt
。我认为文档回答了问题,也许你只是不够熟悉node /其他包管理器。我可能只是因为我知道一些关于Ruby bundler的东西才能理解它。
关键的一行是:
这些内容将在从软件包的根目录执行npm link或npm install时安装,并且可以像任何其他npm配置参数一样进行管理。有关此主题的更多信息,请参见npm-config(7)。
然后在npm-config(7)下找到dev
:
Default: false
Type: Boolean
Install dev-dependencies along with packages.
npm install package
是一个用来安装所有不是开发依赖项的包的命令,而不是我现在认为的意思,也就是“安装叫做[package]的包”,这也是我在阅读之前的理解方式。如果我是你,我会编辑成[package-name],这样就清楚地表明你的意思是“插入这里的名称”。 - Tom Wnpm install
,你会得到B和C,但不会有D。 - Ben HutchisonNODE_ENV
设置为 production
时,devDependencies
不会被安装。 - Augusto Franzoia如果你不想安装devDependencies,你可以使用 npm install --production
命令。
--save
选项不再需要了。如果你运行 "npm install my-package",它会将 my-package 添加到你的 package.json
文件中作为一个依赖项。 - Martin Carel依赖项
指项目运行所需的依赖,比如提供从您代码中调用的函数的库。
它们是传递安装的 (如果 A 依赖于 B 依赖于 C,则在 A 上执行 npm 安装将安装 B 和 C)。
例如:lodash:您的项目调用一些 lodash 函数。
开发依赖项
只在开发或发布期间需要的依赖,比如将您的代码编译成 JavaScript 的编译器、测试框架或文档生成器。
它们不会被传递安装 (如果 A 依赖于 B dev-依赖于 C,则在 A 上执行 npm 安装将仅安装 B)。
例如:grunt:您的项目使用 grunt 来构建自身。
同行依赖项
指您的项目在父项目中钩入或修改的依赖,通常是其他库或工具的插件。它仅作为检查,确保父项目(依赖于您的项目的项目)对您钩入的项目有依赖关系。因此,如果您创建了添加到库 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
以示例说明,mocha通常应是devDependency,因为测试在生产环境中并不必要,而express应该是dependency。
将一个包保存为 dev 依赖项到 package.json:
npm install "$package" --save-dev
当您运行npm install
时,它会安装devDependencies
和dependencies
。如果要避免安装devDependencies
,请运行:
npm install --production
有一些模块和包仅在开发过程中需要,而在生产环境中则不需要。就像文档中所说的那样:(文档链接)
如果别人想要下载和使用你的模块,并将其纳入他们的程序中,那么他们可能不需要也不想要下载和构建你所使用的外部测试或文档框架。在这种情况下,最好将这些额外项列在devDependencies哈希表中。
peerDependencies
对我来说不太容易理解,直到我读到一篇博客文章上关于Ciro上面提到的这个主题的片段:
插件需要一种表达插件与其宿主包之间“依赖关系”的方法。某种方式表达:“只有当我插入到我的宿主包版本1.2.x中时才能工作,因此如果您安装我,请确保它与兼容的宿主一起使用。”我们称这种关系为同级依赖。
peerDependencies
适用于插件,即需要一个“主机”库才能执行其功能的库,但可能是在最新版本的主机发布前编写的。
也就是说,如果我为HostLibraryX v3
编写PluginX v1
并离开,那么不能保证PluginX v1
在发布HostLibraryX v4
(甚至是HostLibraryX v3.0.1
)时仍能正常工作。
But now, [if we treat the contemporary version of HostLibraryX as a dependency for PluginX,] running
npm install
results in the unexpected dependency graph of├── HostLibraryX@4.0.0 └─┬ PluginX@1.0.0 └── HostLibraryX@3.0.0
I’ll leave the subtle failures that come from the plugin using a different [HostLibraryX] API than the main application to your imagination.
...这就是插件的全部意义。现在,如果主机足够友好地包含了{{所有}}插件的依赖信息,那么问题就解决了,但是这也会引入一个巨大的新文化问题:插件管理!
插件的整个意义在于它们可以匿名配对。在完美的世界中,让主机管理所有插件将会整洁而方便,但我们不会要求库来驱动猫。
相反,我们有成为同级的概念。主机和插件都不在对方的依赖桶中。两者都生存在依赖图的同一级别。
如果我是PluginX v1
,并且期望一个同伴(即具有peerDependency of)HostLibraryX v3
,我会这样说。如果你已经自动升级到最新的HostLibraryX v4
(注意这是版本4),并且安装了Plugin v1
,你需要知道,对吧?
npm
无法为我管理这种情况--
"嘿,我看到你正在使用
PluginX v1
!我将自动将HostLibraryX
从v4降级到v3,好吗?"
...或者...
"嘿,我看到你正在使用
PluginX v1
。它期望HostLibraryX v3
,但你在上次更新中已经把它甩在了身后。为了安全起见,我将自动卸载Plugin v1
!!1!
怎么样,npm?不要这样做。
因此,npm不会这样做。它会提醒您这种情况,并让您确定HostLibraryX v4
是否适合Plugin v1
的同伴。
在插件中良好的peerDependency
管理将使这个概念在实践中更加直观。来自博客文章...
一个建议:与常规依赖关系不同,对等依赖关系的要求应该是宽松的。你不应该将你的对等依赖关系锁定到特定的修补程序版本。如果一个Chai插件对Chai 1.4.1有对等依赖,而另一个插件对Chai 1.5.0有对等依赖,那么这将非常令人恼火,因为作者们懒得花时间找出它们与Chai实际兼容的最小版本。
peerDependencies
试图解决的问题。也就是说,你的场景已经处理过了,但如果我们不想使用紧密耦合的依赖关系,我们该怎么办呢?我们将获得更多的灵活性,但npm将无法自动执行这种关系的强制性。如果这符合你的需求,peerDependencies
可以让你实现这一点。 - undefinedpeerDependencies
的作用是允许一个“规范之外”的插件在 libRequirementV4
发布后仍然存在。如果 libDependsV2
能够自动适配新版本,那就太完美了!但是,由于我们告诉了 npm,“这不是你要强制执行的关系”,npm只能“向你提醒这种情况,并让你判断 HostLibraryX v4
是否适合作为 Plugin v1
的对等依赖。” - undefined一个简单的让我更加清楚的解释是:
当你部署你的应用时,依赖中的模块需要被安装,不然你的应用就无法工作。而 devDependencies 中的模块不需要在生产服务器上安装,因为你没有在那台机器上开发。
链接vendor.js
中,那么如果编译后的代码提交到存储库中,所有依赖项都应该是开发依赖项?而且它应该被提交,否则你不仅需要安装模块,还需要编译它(因为任何子模块的更改都可能导致回归测试)... - Qwertiywebpack -p
。请回答我的问题。 - AmerllicA我找到了一个简单的解释。
简短回答:
dependencies "...是你的项目在生产环境中真正需要的依赖项。"
devDependencies "...是你在开发过程中需要的依赖项。"
peerDependencies "如果你想创建和发布自己的库,以便它可以作为依赖项使用。"
更多细节请参阅此帖子: https://code-trotter.com/web/dependencies-vs-devdependencies-vs-peerdependencies
peerDependencies
。 - Tafadzwa Gonera我想补充一下对这些依赖关系解释的看法
dependencies
用于您代码库中直接使用的部分,通常最终会在生产代码或代码块中使用devDependencies
用于构建过程中使用的工具,帮助您管理最终代码的生成方式,包括第三方测试模块(例如webpack等工具)