--save和--save-dev有什么区别?


746

之间有什么区别?

npm install [package_name] --save

和:

npm install [package_name] --save-dev

这是什么意思?


4
是的,对此我感到困惑-如果您使用像Jenkins这样的持续集成,Jenkins是否知道使用devDependencies模块来运行测试?我认为是这样,但这并不是超级明显。
亚历山大·米尔斯

5
也许编辑问题还说,依赖性和devDependencies之间的功能区别是什么?
亚历山大·米尔斯

5
用户执行时,不会重新安装通过--save-dev选项安装的软件包npm install --production。那就是操作上的差异(有关更多信息,请参见https://docs.npmjs.com/cli/install)。
安德鲁

7
@MuhammadUmer这就是人们在这里提出问题的原因-为了“寻找线索”。也许添加一个真实的答案会更有效率-这绝对是我不知道的有趣的区别。
Simon_Weaver

3
同样,如果您将环境变量设置NODE_ENV为生产,那么它将 npm install自动排除开发包。
穆罕默德·乌默

Answers:


589
  • --save-dev用于保存软件包以供开发。示例:单元测试,缩小
  • --save 用于保存应用程序运行所需的软件包。

150
它们有何不同?我何时会使用一个与另一个?如果它在--save-dev下,我仍可以在生产环境中使用它吗?
Dave Voyles,

14
答案简洁地回答了您的前两个问题。对最后一个问题“如果它在--save-dev下,我仍可以在生产中使用该软件包”的答案是“否”。虽然当然有可能这样做,但这不是故意的。
Technetium

61
速记版本:-D的缩写--save-dev-S简称--save
chrisco

164
这个答案令人困惑。即使是一个很小的例子,也将有助于使这一点变得更加清晰。
Choylton B. Higginbottom

33
请注意,从npm 5.0.0版本开始,--save不再需要该选项。如果这样做npm install my-package,它将在package.json文件中添加“ my-package”作为依赖项。
马丁·卡雷尔

642

如果您在自己的项目中都尝试过两者之间的差异--save,则--save-dev可能不会立即注意到。所以这是一些例子...

假设您正在构建一个使用即时包来解析和显示日期的应用程序。您的应用是调度程序,因此它确实需要运行此程序包,例如:没有它就无法运行。在这种情况下,您将使用

npm install moment --save

这将在package.json中创建一个新值

"dependencies": {
   ...
   "moment": "^2.17.1"
}

在开发时,使用测试套件等工具确实很有帮助,并且可能需要jasmine-corekarma。在这种情况下,您将使用

npm install jasmine-core --save-dev
npm install karma --save-dev

这也会在package.json中创建一个新值

"devDependencies": {
    ...
    "jasmine-core": "^2.5.2",
    "karma": "^1.4.1",
}

不需要测试套件即可在正常状态下运行应用程序,因此它是--save-dev类型依赖项,仅此而已。您可以看到如果不了解实际情况,那将很难想象。

直接取自NPM docs docs#dependencies

依存关系

依赖关系是在一个简单的对象中指定的,该对象将程序包名称映射到版本范围。版本范围是一个字符串,具有一个或多个以空格分隔的描述符。依赖关系也可以通过tarball或git URL进行标识。

请不要在您的依赖项对象中放置测试工具或编译器。请参阅下面的devDependencies

即使在文档中,它也会要求您将--save-dev用于测试工具之类的模块。

我希望这会有所帮助并且很清楚。


15
IMO,我认为'save'关键字是一个问题。他们为什么不将-dev标志用于开发,将-deploy用于部署。它比“ save”关键字有意义。
Thinh Vu

1
为什么程序包不仅仅知道(确定)它是发布程序包还是开发程序包,并且--save都用于两者。当软件包开发人员创建意图时,似乎使安装用户决定这一点很奇怪。
CodeGrue

4
CodeGrue,如果仅将jQuery用于测试React组件,它将进入save-dev,但实际上可能不会使用它来构建主项目。是的,这是可能的。那么,为什么包装商会知道您在做什么呢?
Michael Bruce

2
清楚得多。我是一个初次学习Bootstra + Node.js工作流程的嵌入式人员。袖带之间的区别尚不明显。
Leroy105'3

3
@YakovL save-dev表示当其他人将软件包作为依赖项安装时,未安装软件包。在这种情况下,将不需要仅用于运行脚本(例如启动/生成)的软件包,因此它们被置于开发依赖关系中。如果您使用的是Web应用程序,而不是供他人使用的软件包,那么您可能根本不必担心。
riv

110

默认情况下,NPM只是在node_modules下安装一个软件包。当您尝试为应用程序/模块安装依赖项时,您需要先安装它们,然后将其添加到的dependencies部分中package.json

--save-dev将第三方程序包添加到程序包的开发依赖项中。当有人安装您的软件包时,将不会安装它。通常只有在有人克隆您的源存储库并npm install在其中运行时才安装它。

--save将第三方程序包添加到程序包的依赖项中。每当有人运行时,它将与软件包一起安装npm install package

开发依赖项是仅开发软件包所需的那些依赖项。这可以包括测试运行程序,编译器,打包程序等。两种类型的依赖关系都存储在程序包的package.json文件中。--save添加到dependencies--save-dev添加到devDependencies

可以在这里参考npm安装文档。


37
我怀疑这...如果您要构建不会成为软件包的Web应用程序(即从npm下载),则可以交替使用--save-dev和--save,如果您正在开发要与他人共享的软件包,了解差异很重要。
VFein

13
最后,谢谢您,有人在使用npm install时说出了它的目的
CapturedTree'9

3
--save现在是npm install的默认版本,2017
NattyC

等等,为什么句子很复杂?在DevDependecy中,开发人员可以安装软件包,并且只会更新devDevependency。因此,当新的开发人员克隆项目代码库并仅dependency package name is going to install.在node_modules中运行npm install =>时,而不是开发人员的程序包,如Dev-dependency中那样。
阿努帕姆·毛里雅

60

一个完美的例子是:

$ npm install typescript --save-dev

在这种情况下,您希望可以使用Typescript(一种JavaScript解析的编码语言)进行开发,但是一旦部署了该应用程序,就不再需要了,因为所有代码都已被转换为javascript。因此,将其包含在已发布的应用程序中是没有意义的。确实,这只会占用空间并增加下载时间。


4
同样适用于:“ $ npm install grunt --save-dev”,因为它对开发有用,但对部署没有用。
Jackalope

1
旁注:Microsoft建议安装@ types / xxx软件包作为依赖项,而不是devDependencies github.com/Microsoft/types-publisher/issues/81
Dave

2
我感到困惑的是,这到底有什么关系?使用--save保存的软件包仍仅保存在该node_modules文件夹中。该代码未包含在已部署的网站中。
Kokodoko

6
@Kokodoko使用该--save-dev标志时,该包将添加到您的devDependencies对象中。如果/当有人安装您的软件包时,将全部dependencies下载但devDependencies不下载,因为在运行时不需要它们。如答案所述,这可以节省他们的时间和空间。打包文件本身的开发人员也可以npm install在package目录中运行,以进行安装devDependencies
Jasjit Singh Marwah '18

因此,如果您从github下载一个repo并输入npm install,则将devDependencies其忽略?
Kokodoko

40

让我举一个例子,

  • 您是一个非常认真的 npm 的开发人员。使用不同的测试库来测试包。
  • 用户下载了您的库,并希望在其代码中使用它。他们还需要下载您的测试库吗?也许您jest用于测试,而他们使用mocha。您是否也要安装它们jest只是要运行您的库?

没有权利?这就是为什么他们进入devDependencies

当有人这样做时,将仅安装运行npm i yourPackage的库所需的库。您以前用来捆绑代码或进行测试和模拟的其他库将不会安装,因为您将它们放入了。很整洁吧?devDependencies

那么,为什么开发人员需要公开devDependancies

假设您的软件包是一个开源软件包,成百上千的人正在向您的软件包发送请求请求。那么他们将如何测试包装?他们将为git clone您提供仓库,以及何时npm i进行依赖以及devDependencies
因为他们没有使用您的包裹。他们正在进一步开发软件包,因此,为了测试您的软件包,他们需要通过现有的测试用例以及编写新的用例。因此,他们需要使用您的工具devDependencies,其中包含您使用的所有测试/构建/模拟库。


8
这比公认的答案以及具有最高票数的答案要好得多,因为该答案实际上更实用。谢谢!
未捕获的例外情况,

这应该是选择的答案。所有其他答案并没有真正解释为什么您要在另一个答案上使用。
Rocky Kev

34

正如@ andreas-hultgren在此答案中建议的,并根据npm docs

如果有人计划在其程序中下载和使用您的模块,则他们可能不想或不需要下载并构建您使用的外部测试或文档框架。

但是,对于webapp开发,Yeoman(一种安装了经过同行评审的,预先编写的package.json文件的脚手架工具)将所有程序包都放置在devDependencies中,而没有任何依赖项,因此使用似乎--save-dev是一个安全的选择至少在webapp开发中。


3
请注意,在使用gulp并安装软件包时,--save-dev如果软件包无法安装其所需的依赖关系,则会遇到问题。运行--save安装了那些缺少的依赖项。
尼克M

18
我还要指出的是--save,除了测试和文档依赖项之外,我现在都在使用它(根据npm docs)。我开始认为上面提到的Yeoman示例不是最佳实践的好示例。
wayfarer_boy 2015年

我也这样认为,为什么您需要--save-dev的只是这里的每个答案都变得不清楚:)
Kokodoko

20

--save-dev将semver规范保存到程序包描述符文件中的“ devDependencies”数组中,--save而是将其保存到“ dependencies”中。


83
功能上有什么区别?
ahnbizcad 2015年

6
这个答案对我来说最有意义,那么devDependencies是开发而不是生产所必需的,因此htmllint,sass编译等和Dependencies是生产要求,例如Diaporama,必须存在这些东西才能运行。
米勒大猩猩

3
@ahnbizcad 在这里可以更好地回答但主要的功能差异在于,不能将devDependencies包括在传递中。
佩斯

对于不认识的人来说,这不是最直观的描述方式吗?:Dev --save-dev使程序包在项目中本地化,而使程序包--save在节点安装中本地化?
ahnbizcad

9

已经提供了明确的答案。但是值得一提的是如何devDependencies影响安装软件包:

默认情况下,npm install将安装所有列为package.json中的依赖项的模块。使用--production标志(或将NODE_ENV环境变量设置为production时),npm将不会安装devDependencies中列出的模块。

请参阅:https//docs.npmjs.com/cli/install


8

通常,您不希望使用仅用于开发目的的东西来夸大生产包。

使用--save-dev(或-D)选项来分隔诸如单元测试框架(Jest,Jasmine,mocha,chai等)之类的包。

您的应用需要生产的其他任何软件包,都应使用--save(或-S)安装。

npm install --save lodash       //prod dependency
npm install -S moment           // "       "
npm install -S opentracing      // "       "

npm install -D jest                 //dev only dependency
npm install --save-dev typescript   //dev only dependency

如果打开package.json文件,则将在两个不同的部分下看到这些条目:

"dependencies": {
  "lodash": "4.x",
  "moment": "2.x",
  "opentracing": "^0.14.1"
},

"devDependencies": {
    "jest": "22.x",
    "typescript": "^2.8.3"
},

5

--save-dev用于在应用程序开发中使用的模块,在生产环境中运行时不需要 -save用于将其添加到package.json中,并且是运行应用程序所必需的。

示例:express,body-parser,lodash,helmet,mysql所有这些都在运行应用程序时使用–保存以放置依赖项,而在开发过程中使用mocha,istanbul,chai,sonarqube-scanner,因此将它们放在dev中-依赖性。

npm link或npm install还将在您的项目文件夹中安装dev-dependency模块以及依赖模块


3

这里的所有解释都很好,但是缺少一个非常重要的事情:如何仅安装生产依赖项?(没有开发依赖性)。我们单独dependenciesdevDependencies使用--save--save-dev。要安装所有我们使用:

npm i

要仅安装生产软件包,我们应该使用:

npm i --only=production

0

我想补充一些想法

我认为,当有人使用您的代码而不是自己使用代码时,所有的差异都会出现

例如,您编写了一个名为 node's request

在您的书架中

您使用lodash处理字符串和对象,如果没有lodash,则代码无法运行

如果有人将您的HTTP库用作其代码的一部分。您的代码将与他一起编译。

您的代码需要lodash,因此您需要dependencies进行编译


如果您编写了一个项目monaco-editor,例如一个网络编辑器,

您已经捆绑了所有代码,并且product env library使用的webpack在构建完成后仅包含一个monaco-min.js

因此,某人不介意是否--save--save-dependencies,仅他需要的是monaco-min.js

摘要:

  1. 如果有人要编译您的代码(用作库),请将lodash您的代码使用的代码放入dependencies

  2. 如果有人想向您的代码添加更多功能,则需要unit testcompiler,将其放入dev-dependencies


0

人们在生产中使用npm来处理邪恶的事情,Node.js就是一个例子,因此您不希望运行所有开发工具。

如果您正在使用gulp(或类似工具)来创建要放在服务器上的构建文件,那么这并不重要。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.