NPM package.json文件中的 dependencies、devDependencies 和 peerDependencies 有什么区别?

What's the difference between dependencies, devDependencies, and peerDependencies in NPM package.json file?

提问人:Vitalii Korsakov 提问时间:9/18/2013 最后编辑:VLAZVitalii Korsakov 更新时间:3/27/2023 访问量:941929

问:

本文档回答我的问题很差。我不明白这些解释。有人能用更简单的话说吗?如果很难选择简单的词,也许有例子?

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

node.js npm 依赖项 package.json

评论

79赞 Aidan Feldman 6/5/2016
请注意,现在还有 optionalDependencies
312赞 Nick Bull 3/19/2018
@AidanFeldman“optionalDependencies”是我当天的矛盾
6赞 Deke 9/29/2019
npm 文档说: “dependencies”:应用程序在生产中所需的包。“devDependencies”:仅本地开发和测试需要的包。请参阅链接:docs.npmjs.com/...
0赞 Goofy 2/2/2022
依赖项是库使用的包引用,没有这些包,它就无法工作,并且会自动与库安装一起安装。在查看 peerDependencies 时,npm 只会抛出一条警告消息,以防在节点模块中找不到指定的包。它不会为您安装任何软件包。有关详细说明,请参阅链接:medium.com/p/16f43d6c7e45

答:

47赞 Amberlamps 9/18/2013 #1

有些模块和包只有在开发时才需要,在生产中不需要。就像文档中所说的那样:

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

评论

1赞 RegarBoy 9/25/2018
如果您在生产环境中只运行 bundle.js 文件怎么办?你真的需要这些依赖关系吗?
0赞 Stijn de Witt 1/15/2019
如果你在服务器上运行 bundle.js,你正在做服务器端 webpack 或其他东西......请检查是否是这种情况,因为通常不是这样,实际上需要做很多工作才能使其正常运行(我知道,因为我这样做了)。我怀疑您的 bundle.js 只是提供给浏览器并包含客户端代码。
1赞 Viraj Singh 1/5/2022
让我感到困惑的部分是,这里的生产是什么?是CDN服务器,我部署我的构建,还是运行我的构建的客户端浏览器?
151赞 Dan Kohn 9/19/2013 #2

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

评论

5赞 1/11/2014
我倾向于将测试作为依赖项,因为您可能希望在启动生产服务器之前运行自检
61赞 Dan Kohn 1/12/2014
相反,我建议使用像 Hudson 或 CircleCI 这样的持续集成服务来运行您的测试,然后在测试通过后部署到生产环境。
1赞 Nicole 3/26/2016
测试实际服务器可能仍然相关,因为 CI 服务器可能与生产服务器有所不同,这种差异可能会阻止应用程序启动......
2赞 Lucas 11/20/2017
@Nicole为什么要使暂存服务器的配置与产品不同呢?
2赞 Stijn de Witt 1/15/2019
话又说回来,将测试依赖项添加为常规依赖项会引入一大堆额外的库,每个库都可能以某种方式失败。我会倾向于(双关语!)轻量级的生产服务器,尽可能少地使用代码。请记住,最好的代码是没有代码!
3202赞 Ciro Santilli OurBigBook.com 2/25/2014 #3

重要行为差异摘要:

  • 依赖项安装在两者上:

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

    • 也安装在包含 的目录上,除非您传递标志(为 Gayan Charith 的答案投赞成票),或者如果设置了环境变量npm installpackage.json--productionNODE_ENV=production
    • 不安装在任何其他目录上,除非您给它选择。npm install "$package"--dev
    • 不是可传递安装的。
  • peerDependencies

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

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

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

此处未讨论的相关选项:

dev依赖项

dependencies需要运行,只能进行开发,例如:单元测试、CoffeeScript 到 JavaScript 的转译、缩小......devDependencies

如果你要开发一个包,你可以下载它(例如通过),转到它的根目录,其中包含,然后运行:git clonepackage.json

npm install

既然你有实际的源代码,很明显你想开发它,所以默认情况下,也会安装(因为你必须运行才能开发)和依赖项。dependenciesdevDependency

但是,如果您只是一个只想安装软件包来使用它的最终用户,则可以从任何目录执行以下操作:

npm install "$package"

在这种情况下,您通常不需要开发依赖项,因此您只需获得使用包所需的内容:.dependencies

在这种情况下,如果您确实想安装开发包,则可以将配置选项设置为 ,可能从命令行设置为:devtrue

npm install "$package" --dev

该选项是默认的,因为这种情况不太常见。false

peer依赖关系

(在 3.0 之前测试)

来源:https://nodejs.org/en/blog/npm/peer-dependencies/

使用常规依赖项,可以拥有多个版本的依赖项:它只是安装在依赖项的内部。node_modules

例如,如果 和 两者都依赖于不同的版本,则项目树将如下所示:dependency1dependency2dependency3

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

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

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

例如,if 和 peer depend on ,项目树将如下所示:dependency1dependency2dependency3

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/

然后,当用户使用插件时,他会通过添加一行来隐式要求插件,但用户会直接调用。Gruntfilegrunt.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.

评论

9赞 Tom W 3/18/2014
啊。我看我误会了。你的回答读起来好像是你用来安装所有不是开发依赖项的包的命令,而不是我现在认为你的意思,即“安装名为 [package] 的包”,这就是我在阅读本文之前认为它的工作方式。如果我是你,我会编辑说 [package-name],这清楚地表明你的意思是“insert-name-here”。npm install package
306赞 8/29/2014
这太棒了!我从来没有意识到,但这个答案告诉我,依赖项与 devDependencies 的区别仅适用于您要发布 npm 包的情况。如果您只是在应用程序或网站上工作,那应该不会太重要。谢谢!
7赞 nextgentech 5/22/2015
这篇文章应该更新,以反映即将到来的npm@3中更改的行为。来自 blog.npmjs.org/post/110924823920/npm-weekly-5:“我们将不再自动下载对等依赖项。相反,如果尚未安装对等依赖项,我们会发出警告。这需要你自己手动解决peerDependency冲突,但从长远来看,这应该会降低你最终陷入包依赖关系的棘手境地的可能性。peerDependencies
13赞 Ben Hutchison 1/23/2016
此外,devDependencies 不会由依赖包传递安装。示例:包 A 依赖于包 B,包 B 依赖于包 C,而 B 也依赖于包 D。如果从包 A 运行,则将获得 B 和 C,但不会获得 D。npm install
28赞 Augusto Franzoia 8/5/2018
请务必注意,当设置为 时未安装。devDependenciesNODE_ENVproduction
636赞 Gayan Charith 7/5/2015 #4

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

评论

1赞 Vamsi Pavan Mahesh 7/27/2015
npm install --save 是为了依赖软件吗?
24赞 Gayan Charith 9/13/2015
npm install 将安装所有依赖项。--save 标志,当您也想将特定模块添加到package.json时使用。例如:- npm install uglify --save 将在您的项目文件夹中安装 uglify,并将 uglify 添加到项目package.json文件中。
7赞 Mykaelos 9/30/2016
因为我们谈论的是 devDependencies,所以你可以使用 --save-dev 将新模块保存为 devDependency。示例:npm install uglify --save-dev
25赞 Martin Carel 2/24/2018
从 npm 5 开始,不再需要该选项。如果你执行“npm install my-package”,它会将 my-package 添加为文件中的依赖项。--savepackage.json
2赞 Stijn de Witt 1/15/2019
从 npm 5 开始,不再需要 --save 选项。这是个好消息!我以前没有意识到这一点。我总是觉得很烦人,大多数文档都忽略了这个选项,而实际上,不保存您添加依赖项的事实几乎没有意义。--save
81赞 Mohammed Safeer 1/8/2016 #5

要将包保存为开发依赖项package.json,请执行以下操作:

npm install "$package" --save-dev

当您运行时,它将同时安装 和 .若要避免安装,请运行:npm installdevDependenciesdependenciesdevDependencies

npm install --production

评论

5赞 maysara 7/29/2017
你也可以使用:npm i -S
161赞 qwertzguy 9/6/2017 #6


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

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

peerDependencies
项目在父项目中挂接到或修改的依赖项,通常是其他库或工具的插件。它只是一个检查,确保父项目(将依赖于你的项目)对你挂钩的项目有依赖关系。因此,如果你制作了一个插件 C 来向库 B 添加功能,那么制作项目 A 的人如果依赖于 C<,就需要依赖 B。

示例: 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

评论

9赞 fires3as0n 1/26/2021
应该作为“答案”——清晰整洁,“peerDependencies”下的第一句话正确地解释了所有内容,而没有深入研究如何在 npm 中解析版本,而 npm 不需要了解 peerDependecies 的用途。
3赞 Joe Fitzsimmons 1/28/2022
最后,peerDependencies 的答案满足了“为什么?”而不是“如何?”。很有帮助!
2赞 Girish Ingle 10/4/2022
peerDependencies 的明确答案!谢谢
25赞 Jyoti Duhan 9/29/2017 #7

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

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

评论

3赞 Qwertiy 10/2/2017
因此,如果我们正在制作网站并且在 prod 版本中,所有库都将内联到 ,如果编译后的代码被提交到存储库中,我们所有的 deps 都应该是 dev deps?它应该被提交,因为其他的很奇怪,你必须编译模块,而不仅仅是安装它(测试也在这里的某个地方,因为子模块的任何变化都可能导致回归)......vendor.js
0赞 AmerllicA 11/29/2017
很棒的答案,但有一个问题?Webpack 是否可能构建损坏的捆绑包?我的意思是,我的猜测是devDependencies包在产品版本中不起作用。请回答我的问题。webpack -p
0赞 Jyoti Duhan 12/5/2017
如果在生产构建时出现任何问题,您的部署过程应设计为在构建时显示错误,并且不会将损坏的代码推送到生产环境(例如,您可以尝试 Jenkins)。无论如何,不需要在生产服务器上安装 Devdependencies。
20赞 Sîrbu Nicolae-Cezar 2/16/2018 #8

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

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

评论

0赞 Brian Zelip 3/28/2019
CSS资产呢?
3赞 Melchia 7/6/2018 #9

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

更新

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

评论

2赞 Nico Haase 6/30/2020
请在您的答案中添加一些解释,以便其他人可以从中学习 - 为什么要避免使用?dependencies
0赞 Melchia 11/8/2021
大多数时候,依赖项只是一堆描述生态系统的库。除非您确实使用的是某个特定版本的库,否则您应该让用户选择是否安装该库以及选择哪个版本,方法是将其添加到 peerDependencies 中。
0赞 Nico Haase 11/8/2021
请通过编辑为您的答案添加所有澄清
0赞 Melchia 11/8/2021
@NicoHaase 如果您有任何问题,请告诉我
30赞 ruffin 8/29/2018 #10

peerDependencies直到我从上面提到的 Ciro 主题的博客文章中读到这个片段,对我来说才完全有意义:

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

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

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

也就是说,如果我写了然后走开了,就不能保证在发布时(甚至)会起作用。PluginX v1HostLibraryX v3PluginX v1HostLibraryX v4HostLibraryX v3.0.1

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

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

这意味着依赖关系并不是插件的正确概念。

更糟糕的是,如果我的主机被视为依赖项,我们最终会陷入同一篇博文提到的这种情况(编辑了一点以使用这个答案的虚构主机和插件):

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

├── [email protected]
└─┬ [email protected]
  └── [email protected]

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

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

...这就是插件的全部意义所在。现在,如果主机足够好,可以包含其所有插件的依赖信息,这将解决问题,但这也会带来一个巨大的新文化问题:插件管理!

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

如果我们不是分层依赖的,也许我们是内部依赖的对等方......

相反,我们有成为同行的概念。主机和插件都不位于对方的依赖项存储桶中。两者都位于依赖关系图的同一级别。


...但这不是一种自动化的关系。<<<点球成金!!

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

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

“嘿,我看你在用!我会自动从 v4 降级到 v3,kk?PluginX v1HostLibraryX

...或。。。

“嘿,我看到你用的.这期望 ,您在上次更新期间将其留在了尘埃中。为了安全起见,我会自动卸载!1!PluginX v1HostLibraryX v3Plugin v1

不,npm怎么样?!

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


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

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

评论

0赞 Alois Mahdal 9/12/2023
我仍然不明白插件不依赖于需要主机包的论点——真的有什么区别?如果只是插件不需要/导入主机库,那么这似乎是一个技术问题,人们仍然可以说插件依赖于它,显然它仍然依赖于(通过实现)它定义的接口
0赞 ruffin 9/12/2023
@AloisMahdal你用人类的逻辑和定义来定义这些词,但我们必须在这里专业化。如果 libDependsV2 依赖于 libRequirement V3,则在 npm-land 中,如果 libDependsV2 在 package.json,则将安装 libRequirementV3。我们不希望插件出现这种情况。关键是这句话:“如果你没有主机,插件不会无害地做任何事情。如果插件没有“优雅地失败”,我们就会遇到问题。但是,该插件期望存在对等关系,并且当[且仅当]找到兼容的主机时,该插件才会“活跃起来”。否则,您最终会遇到我上面描述的管理问题。
0赞 ruffin 9/12/2023
回顾...但是插件不依赖于主机...部分。这是一个很好的(“小”)区别,如果你愿意,你可以写一个使用传统依赖项的“插件”,但这种紧密的耦合是试图解决的。也就是说,您的方案已经处理完毕,但是如果我们不想使用紧密耦合依赖项,我们该怎么办?我们会得到更大的灵活性,但 npm 无法再自动执行这种关系。如果这适用于您想要完成的任务,请让您去做。peerDependenciespeerDependencies
0赞 ruffin 9/13/2023
最后,这篇博客在这里提出了一个很好的观点:“一条建议:与常规依赖关系不同,对等依赖关系的要求应该是宽松的。对您来说,即使 libRequirementV4 发布,也允许“超出规格”的插件仍然存在。如果它 libDependsV2 自动与新版本一起工作,那就完美了!但是,既然我们已经告诉 npm,“这不是你要强制执行的关系”,那么 npm 只能“提醒你注意这种情况,并让你弄清楚 HostLibraryX v4 是否是插件 v1 的合适对等体。peerDependencies"
11赞 cherankrish 6/7/2019 #11

总之

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

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

  3. 只需键入即可安装 package.jsonnpm install

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

8赞 Selva Ganapathi 7/29/2019 #12

依赖项与开发依赖项

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

例如-反应,反应-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
24赞 user739DamQ 2/4/2020 #13

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

简短的回答:

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

dev依赖项"...是你在开发过程中需要的那些。

peer依赖关系“如果你想创建和发布你自己的库,以便它可以作为一个依赖项使用”

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

评论

0赞 Tafadzwa Gonera 2/9/2021
顶级答案非常具有描述性和详细性,但这个答案对我来说是 ELI5。peerDependencies
3赞 Quantalabs 10/13/2020 #14

依赖

这些是你的包需要运行的包,因此它们将在用户运行时安装

 npm install PACKAGE-NAME

例如,如果您在项目中使用了 jQuery。如果有人没有安装jQuery,那么它就不起作用。要另存为依赖项,请使用

 npm install --save

开发依赖关系

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

npm install PACKAGE --save-dev

对等依赖关系

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

0赞 Sagar M 2/17/2022 #15

依赖项是需要运行的,devDependencies 只需要开发

评论

0赞 Yunnosch 4/30/2022
一个基本上提出与现有答案相同的解决方案的答案在理论上仍然是一个有价值的贡献,如果它解释了更多,或者从不同的角度,或者更易于理解......但这篇文章没有。请不要指望用户会觉得这篇文章有帮助。
6赞 Juanma Menendez 3/9/2022 #16

dependencies:项目/包在生产环境中需要使用的包。

devDependencies:您的项目/包在开发时需要工作但在生产中不需要的包(例如:测试包)

peerDependencies:你的项目/包需要协同工作(与它们“合作”)或作为基础的包,主要在你开发插件/组件时有用,让你知道你的插件/组件应该使用哪个版本的“main”包(例如:React 16)

1赞 ArturZ 6/30/2022 #17

当使用 Webpack 捆绑前端应用程序时,dependencies 和 devDependencies 之间的区别并不那么清楚。对于最终的捆绑包,将依赖项放在哪里并不重要(但对于其他工具可能很重要)。这就是为什么文档看起来令人困惑的原因。

我在这里找到了解释:使用 Webpack 时,“依赖项”和“devDependencies”重要吗?