如何防止安装 Node.js(package.json)的“devDependencies” NPM 模块?

850

我在我的 package.json 文件中有以下内容(缩短版):

{
  "name": "a-module",
  "version": "0.0.1",
  "dependencies": {
    "coffee-script":      ">= 1.1.3"
  },
  "devDependencies": {
    "stylus":             ">= 0.17.0"
  }
}

我在Mac 10.6.8上使用NPM版本1.1.1。

当我从项目根目录运行以下命令时,它会同时安装dependenciesdevDependencies

npm install

我原本认为这个命令会安装 devDependencies

npm install --dev

如何使npm install仅安装dependencies(因此生产环境只获取这些模块),而像npm install --dev这样的命令则同时安装dependenciesdevDependencies


1
根据文档,你是对的,--dev 安装 devdeps,否则只安装 deps。http://npmjs.org/doc/json.html。我至少知道这适用于命名的 packages。 - mna
2
如果您在2015年遇到了这个问题,--save-dev开关正好可以像本问题中所要求的那样解决问题。 - Anand
2
这个回答 https://dev59.com/VmMk5IYBdhLWcg3w5B3y#22004559 很好地解释了dependenciesdevDependencies之间的区别以及它们各自使用的情况。 - quasoft
16个回答

1293

npm install 命令在包目录中运行时,会安装开发环境(默认)中的 dependenciesdevDependencies

从版本 8.x 开始,请使用 --omit=dev 标志只安装常规依赖项:

npm install --omit=dev
这将仅安装“依赖项”,而不管NODE_ENV环境变量的值如何,也不会安装devDependencies
如果您使用6.x或更早版本,则需要使用--only=prod标志。
注意:
在npm的v3.3.0之前(2015-08-13),该选项称为--production
npm install --production

您可能还需要使用 --no-optional 标志。


5
Agate可能的推理是移除devDependencies,这样通过npm install yourpackage.tgz安装你的包的用户将不会得到devDependencies。然而,这已经是事实。请参见Kevin Cox在下面的回答(https://dev59.com/hGox5IYBdhLWcg3wVS8J#15826602)。 - Johann
7
默认情况下,npm install命令将安装列在dependencies中的所有模块。使用 --production 标志,npm 将不会安装列在devDependencies中的模块。 - tomByrer
30
天哪,我之前在做其他事情时完全设置了NODE_ENV=production,我始终无法弄清楚为什么npm install无法安装依赖项。感谢您详尽的回答。 - aendra
11
从npm 3.3开始:npm WARN install警告,使用“--dev”选项已过时,请改用“--only=dev”。 - srcspider
5
根据当前的文档,仍然只有使用--production参数才能实现:"使用--production标志(或者将 NODE_ENV 环境变量设置为 production),npm 将不会安装 devDependencies 中列出的模块。" - João Pimentel Ferreira
显示剩余7条评论

310

我也遇到过这个问题!npm install 命令有点令人困惑,而且网页文章总是把 -d/--dev 标志引入进来,好像有一个显式的“开发”安装模式。

  • npm install 命令将同时安装“dependencies”和“devDependencies”。

  • npm install --production 命令只会安装“dependencies”。

  • npm install --dev 命令只会安装“devDependencies”。


63
警告:如果将 NODE_ENV 设置为 production 并运行 npm install,它将不会安装开发依赖项。我在我的 Dockerfile 中遇到了这个问题。 - vaughan
6
@vaughan 我也遇到过这个问题,可以通过运行 npm --production=false install 来解决(不确定是否与 --dev 标志一起使用会起作用)。 - Bavell
@vaughan 如果 echo $NODE_ENV 返回空值怎么办? - JarsOfJam-Scheduler
为什么有人会使用npm install --dev?在什么情况下使用?例如,他们已经通过npm install --production进行了安装,现在决定进行一些测试? - Jim Raynor
@JimRaynor 我有一个项目,其中生产依赖项全局安装,开发依赖项本地安装。这是一个测试工具,因此不是通常的用例(也不是我设计的方式),但它绝对是一个用例。我们使用 -g 标志运行 --production,并且不带 -g 运行 --dev。 - Roddy of the Frozen Peas

164

新选项为:

npm install --only=prod

如果您只想安装 devDependencies:

npm install --only=dev

1
这个回答回答了与问题相反的内容。OP正在询问如何不安装devDependencies。 - musicin3d
4
你部分正确 @musicin3d,这就是为什么在第一部分中我回答了如何安装仅限于生产环境的依赖项,而在第二部分中回答了如何安装仅限于开发环境的依赖项,以防万一。 - Cloxure
7
嘿,我之前留言的时候 @user1614572 还没有加上 --only=prod 部分。您,先生,部分正确。 ;P - musicin3d
1
@Jacques:我没有错过重点,但让我澄清一下:在你评论时,文档 显示了两个选项,并没有说明哪个是首选或新的。是什么让你声称“这是正确的答案”?此外,两个选项今天仍然都是有效的,如果你关心诚信,你应该删除你的2016年的评论,如果你有理由说--production已经被弃用,也可以添加一个新的评论。SO不是一个静态博客文章,它是一个不断进化的维基百科。让我们保持最新的信息! - Dan Dascalescu
3
这是一条评论,不是回答。我不会定期检查所有的评论。我从来没有看到有人更新几年前的评论。你基本上是来批评我在评论中加了一个年份。我不会再做回应了。祝你在别人的帖子里玩得开心。 - Jacques ジャック
显示剩余5条评论

56
如果您已经安装了所有依赖项,并且想避免再次从NPM下载生产包,那么只需输入以下命令:
npm prune --production

这将从你的node_modules文件夹中删除开发依赖项,如果你想要自动化一个两步骤的过程,比如:

  1. 使用开发依赖项对我的项目进行Webpack打包
  2. 仅使用生产模块构建Docker镜像

在两个步骤之间运行npm prune将避免你不得不重新安装所有内容!


2
在2021年,npm v7.11中,即使您安装了整个包,您只需要运行npm install --only=production命令,就可以达到相同的结果。 - santiago arizti
1
2023年,npm在使用--only=production时发出警告,内容如下: npm警告:请使用--omit=dev来从安装中省略开发依赖。 - elad.chen

47

如果您在2016年阅读此POST,请使用以下方式实现您的目标

--only={prod[uction]|dev[elopment]} 

使用该参数会导致只安装devDependencies或只安装non-devDependencies,而不考虑NODE_ENV。

来自:https://docs.npmjs.com/cli/install


1
为什么要将“POST”大写?https://docs.npmjs.com/cli/install清楚地记录了“--production”和“--only={prod[uction]|dev[elopment]}”两者。 - Dan Dascalescu

23

使用 "npm install" 命令时,无论是 "devDependencies" 还是 "dependencies",模块都会被加载并在整个应用程序中可用。总的来说,package.json 中定义为依赖项(任何类型)的所有内容都会安装到 node_modules。

dependencies/devDependencies/optionalDependencies 的区别是消费者在使用 npm 安装这些资源时可以做什么。

根据文档:https://npmjs.org/doc/json.html...

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

在这种情况下,最好将这些附加项列在 devDependencies 散列中。

这些内容将在设置了 --dev 配置标志时安装。当使用 npm link 或从包的根目录执行 npm install 时,该标志会自动设置。可以像其他 npm 配置参数一样管理此标志。有关更多信息,请参见 config(1)。

但如果你想仅使用 npm 安装 "dependencies",则可以使用以下命令:

npm install --production

通过查看添加此筛选器的Git提交(以及其他列出的一些筛选器),可以确认此事。

npm可用的替代筛选器:

--save          => updates dependencies entries in the {{{json}}} file
--force         => force fetching remote entries if they exist on disk 
--force-latest  => force latest version on conflict
--production    => do NOT install project devDependencies
--no-color      => do not print colors

@dmarr 请尝试使用npm install --production命令。


18

我建议使用 npm ci。如果你只想安装必要的生产环境包(就像你写的那样 - 不需要 devDependencies ),那么:

npm ci --only=production
或者
NODE_ENV=production npm ci

如果你更喜欢老派的npm install,那么:

npm install --production
或者
NODE_ENV=production npm install

这里有一个好答案解释了为什么您应该使用npm ci


很酷,它也可以与npm ci一起使用,不仅仅是npm install - Klesun
1
这是很好的建议。然而现在 --only=production 应该改为 --omit=dev - Subfuzion

18

当从包内部安装(如果当前目录中存在 package.json 文件)时,npm 会同时安装开发依赖项。但是,如果从其他位置(如 npm 注册表、git 仓库或文件系统的不同位置)安装,则只会安装相关依赖。


请问您能否重新表述一下?我认为您在括号中犯了一个错误,可能之前忘记关闭了括号,导致您的句子对我来说不太有意义(非英语母语者)。Johann在Rohan Singh的回答下发表的评论提示我查看了您的回答(因为我的疑惑与agate的疑惑完全相同),但并没有解决我的问题。我仍然不明白npm install some-module如何不会安装some-module的开发依赖项。 - Rafael Eyng
谢谢,问题已解决。但是我不明白你问题的其他部分。 - Kevin Cox

7

值得一提的是,您可以使用NODE_ENV环境变量来实现相同的结果。如果您正在容器化您的Node应用程序(例如Docker),则尤其有用。

NODE_ENV=production npm install

上述代码将安装所有依赖项,但不包括开发环境依赖项(即devDependencies)。
如果您需要在Dockerfile中使用环境变量,则可以在此处找到更多信息。
环境变量很容易被覆盖,以满足需要(例如,如果您想在Travis CI上运行测试套件)。如果是这种情况,您可以执行以下操作:
docker run -v $(pwd):/usr/src/app --rm -it -e NODE_ENV=production node:8 npm install

此处 NPM 文档

production

  • 默认值:false
  • 类型:布尔型 设置为 true 以运行“生产”模式。

    1. 在本地运行 npm install 时,不会安装 devDependencies 到最高层级。
    2. 为生命周期脚本设置 NODE_ENV="production"。

祝你容器化愉快 =)


6

npm install --production --no-optional

它仅安装来自dependencies的依赖项,并将忽略optionalDependenciesdevDependencies


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接