npm package.json文件中依赖项,devDependencies和peerDependencies之间有什么区别?

时间:2013-09-18 14:57:07

标签: node.js npm

This documentation很难回答我的问题。我不明白这些解释。有人可以用简单的话说吗?如果很难选择简单的单词,可能还有例子吗?

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

14 个答案:

答案 0 :(得分:2050)

重要行为差异摘要:

  • dependencies安装在两者上:

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

    • 也在npm install上安装在包含package.json的目录上,除非您传递--production标记(go upvote Gayan Charith's answer)。
    • 未安装在任何其他目录的npm install "$package"上,除非您为其提供--dev选项。
    • 没有过渡安装。
  • peerDependencies

      3.0之前的
    • :如果丢失则总是安装,如果不同的依赖项将使用多个不兼容的依赖版本,则会引发错误。
    • expected to start on 3.0(未经测试):如果在npm install上遗失,则发出警告,您必须自己手动解决依赖关系。运行时,如果缺少依赖项,则会出现错误(由@nextgentech提及)
  • 及物性(由Ben Hutchison提及):

      传递性地安装
    • dependencies:如果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内。

E.g。如果dependency1dependency2在不同版本中都依赖于dependency3,则项目树将如下所示:

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

插件通常不需要其他软件包,在此上下文中称为 host 。代替:

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

E.g。如果dependency1dependency2对等体依赖于dependency3,则项目树将如下所示:

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

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

我认为这是Inversion of Control设计模式的一个实例。

对等依赖项的典型示例是Grunt,主机及其插件。

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

  • gruntpeer-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.

答案 1 :(得分:421)

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

答案 2 :(得分:99)

作为一个例子,mocha通常是一个devDependency,因为在生产中测试不是必需的,而express是一个依赖。

答案 3 :(得分:58)

将包保存为 package.json 作为dev依赖项:

npm install "$package" --save-dev

当您运行npm install时,它会同时安装devDependenciesdependencies。要避免安装devDependencies运行:

npm install --production

答案 4 :(得分:41)

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

<强> devDependencies
您在开发或发布期间只需要的依赖关系,例如将您的代码编译成javascript,编译框架或文档生成器的编译器。
它们没有传递安装(如果A依赖于B dev-依赖于C,则A上的npm安装将仅安装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/doc/files/package.json.md#devdependencies

答案 5 :(得分:33)

开发时只需要一些模块和包,生产中不需要这些模块和包。就像它在documentation中所说的那样:

  

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

答案 6 :(得分:12)

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

部署应用时,需要安装依赖项中的模块,否则您的应用无法运行。 devDependencies中的模块不需要安装在生产服务器上,因为您没有在该计算机上进行开发。 link

答案 7 :(得分:9)

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

  • dependencies用于代码库中的直接使用,通常最终出现在生产代码中的内容或代码块
  • devDependencies用于构建过程,帮助您管理最终代码最终结果的工具,第三方测试模块,(例如webpack stuff)

答案 8 :(得分:8)

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

简短答案:

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

devDependencies “ ...是您在开发过程中所需的。”

peerDependencies “如果您要创建和发布自己的库,以便可以将其用作依赖项”

此帖子中的更多详细信息: https://code-trotter.com/web/dependencies-vs-devdependencies-vs-peerdependencies

答案 9 :(得分:2)

依赖与开发依赖

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

Eg- React,React-dom

Dev依赖关系模块不需要安装在生产服务器中,因为您不需要在该机器上进行开发。将代码隐藏为javascript的编译器,测试框架和文档生成器可以视为开发依赖项,因为它们仅在以下情况下才需要开发。

例如,ESLint,Babel,webpack

@FYI,

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

答案 10 :(得分:1)

简而言之

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

  2. DevDependencies -安装npm install <package> --save-dev     仅用于本地开发和测试的软件包

  3. 只需键入npm install,即可安装 package.json

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

答案 11 :(得分:0)

尝试分发npm软件包时,应避免使用 content = unicode(s3core.download_file_to_memory(S3_PROFILE, S3_RAW + file), "utf8", "ignore") rows = content.split('\n')[1:] for row in rows: if not row: continue try: # fetch variables cols = row.rstrip('\n').split(',') transaction = cols[0] device_category = cols[1] campaign = cols[2] source = cols[3].split('/')[0].strip() medium = cols[3].split('/')[1].strip() ad_group = cols[4] transactions = cols[5] data_list.append('\t'.join( ['-'.join([dt[:4], dt[4:6], dt[6:]]), country, transaction, device_category, campaign, source, medium, ad_group, transactions])) except: print 'ignoring row: ' + row 。相反,您需要考虑将其添加到dependencies或从peerDependencies中删除。

答案 12 :(得分:0)

peerDependencies对我来说意义不大,直到我阅读了a blog post中有关主题Ciro mentioned above的摘录:

  

[插件”需要的是一种表达插件及其主机包之间的“依赖关系”的方式。可以这样说:“我只有在插入主机程序包的1.2.x版本时才能工作,因此,如果您安装了我,请确保它与兼容主机并排。”我们将此关系称为对等依赖项。

插件确实期望特定版本的主机...

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

也就是说,如果我为PluginX v1HostLibraryX v3并走开,则无法保证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来解决由插件引起的细微故障。

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

...这就是插件的重点。现在,如果主机足够好,可以为其插件的所有 all 包括依赖项信息,则可以解决此问题,但是这也将带来一个巨大的新文化问题:插件管理!

插件的全部目的是它们可以匿名配对。在一个理想的世界中,让主人来管理它们会很整洁,但是我们不会要求图书馆放牧猫。

如果我们不是分层依赖的,也许我们是内部依赖的同行...

相反,我们有同伴的概念。主机和插件都不位于另一个的依赖项存储桶中。两者都生活在依赖图的同一级别。

...但这不是自动关系。

如果我是PluginX v1,并且期望(即具有peerem HostLibraryX v3的同伴,我会说所以。如果您已自动升级到最新的HostLibraryX v4(请注意,版本为 4 ),则 AND 已安装Plugin v1 ,您需要知道,对吧?

npm对我来说无法解决这种情况-

  

“嘿,我看到您正在使用PluginX v1!我正在将HostLibraryX从v4降级到v3,kk?”

...或...

  

”“嘿,我看到您正在使用PluginX v1。这应该是HostLibraryX v3,您在上一次更新时就将其遗忘了。为了安全起见,我会自动卸载{{1 }} !! 1!

不,npm吗?!

所以npm不会。它会提醒您情况,并让您找出Plugin v1是否适合HostLibraryX v4的同伴。


Coda

插件中良好的Plugin v1管理将使该概念在实践中更直观地发挥作用。从the blog post起,再次...

  

一条建议:对等依赖性要求,与常规依赖性要求不同,应该宽松。您不应将对等依赖项锁定到特定的补丁程序版本。如果一个Chai插件同等地依赖Chai 1.4.1,而另一个依赖Chai 1.5.0,那真是令人讨厌,这仅仅是因为作者很懒,并且没有花时间确定他们的实际最小Chai版本。兼容。

答案 13 :(得分:0)

依赖项

这些是您的程序包需要运行的程序包,因此将在人们运行时安装。

 npm install PACKAGE-NAME

一个例子是,如果您在项目中使用了jquery。如果某人没有安装jquery,则它将无法正常工作。要保存为依赖项,请使用

 npm install --save

Dev依赖项

这些是您在开发中使用的依赖关系,但是当人们使用它时并不需要这些依赖关系,因此当人们运行npm install时,由于不需要安装,因此不会安装它们。例如,如果您使用Mocha进行测试,则人们不需要运行Mocha,因此npm install不会安装它。要保存为开发人员依赖项,请使用

npm install PACKAGE --save-dev

对等依赖

如果您要创建和发布自己的库以便可以将其用作依赖项,则可以使用这些库。例如,如果您不想将软件包用作其他项目的依赖项,那么当有人安装的项目将您的项目作为依赖项时,也将安装这些软件包。大多数时候,您不会使用对等关系。