如何使用 Nodemon 自动重启 Node.js 应用

引言
在开发 Node.js 应用时,每次修改文件后,你都必须停止并重启进程,才能让改动生效。这种手动操作给开发流程增加了摩擦和重复性工作。
你可以使用 nodemon 来消除这个多余的步骤。它是一个命令行界面(CLI)工具,能在检测到项目目录中的文件变化时,自动重启你的 Node.js 应用。它本质上是 node 命令的一个包装器,能够监视文件系统并重启进程。
在本文中,你将学习如何安装 nodemon,用它来运行一个 Express 示例项目,并通过命令行选项和 nodemon.json 文件来配置其行为。你还将了解 nodemon 的工作原理、为什么它只适用于开发环境,以及如何解决常见问题。
核心要点:
- 它的主要目的是通过在文件变化时重启应用来加速开发。生产环境需要的是进程管理器(如 PM2 或
systemd),它会在应用崩溃时重启,并负责管理稳定性。- 使用
nodemon的推荐方式是将其作为本地开发依赖项安装(npm install nodemon --save-dev),并通过package.json的scripts部分来运行它(例如,"dev": "nodemon server.js")。- 虽然命令行标志也能用,但使用
nodemon.json文件是一种更清晰、更易于共享的配置管理方式。你可以定义特定的watch路径、ignore模式以及要监控的文件扩展名。nodemon默认只监视特定的扩展名。默认情况下,nodemon只会在.js、.mjs和.json文件发生变化时重启。如果你希望它监视其他文件,比如.env或.ts,你必须将它们明确添加到ext(扩展名)配置中。- 如果
nodemon没有重启,很可能有两个原因:你正在编辑一个它没有监视的文件(可以通过ext配置解决),或者你的文本编辑器使用了“安全写入”功能,这需要启用旧版的监视标志(-L)。- 如果你的应用启动后立即崩溃并陷入无限循环,这不是
nodemon的 bug。这意味着你的应用在启动时就出错了。请检查终端中的代码错误信息。- 你不需要停止再启动
nodemon来强制重启。只需在运行nodemon的终端中输入rs并按回车键即可。
准备
- 一台云服务器
如果没有,可以前往 雨云- 新一代云服务提供商 进行注册,新用户有五折优惠。
全产品线路优化:
- 香港CN2三网直连,延迟低至35ms;
- 美国(CMI+9929),延迟低至140ms;
- 日本东京三网直连,延迟低至60ms;
更有国内:浙江宁波、广东深圳、广东广州、湖北襄阳、江苏宿迁、重庆电信 地区服务器,价格平民,质量优质,CPU强劲。

拥有:云应用、云服务器、游戏云、显卡云、对象存储、裸金属物理机、域名服务、SSL证书、虚拟主机、雨盾CDN 产品

新用户更有五折券优惠,支持一元使用!点击进行注册
先决条件
要学习本教程,你需要:
- Node.js 和 npm: 本教程已在 Node.js 22.20.0 和 npm 10.9.3 版本下测试。你可以按照这篇指南在本地机器上安装 Node.js 和 npm。
Nodemon 是如何工作的?
nodemon 会包装你的应用执行命令(例如 node server.js),并监控项目目录中的文件变化。
默认情况下,它会监视当前工作目录。当它检测到具有指定扩展名(如 .js、.mjs 或 .json)的文件被添加、修改或删除时,它会自动执行一个操作:向子进程(你的应用)发送一个 SIGUSR2 信号来终止它,然后立即启动一个新进程来再次运行你的应用。
这种文件监视机制依赖于操作系统内置的文件系统事件 API(例如 Node.js 中的 fs.watch,它在 Linux 上使用 inotify,在 macOS 上使用 FSEvents)。这种方式非常高效,不需要持续轮询,从而减少了 CPU 的使用。然而,某些文本编辑器或虚拟化文件系统可能会干扰这些事件,这时就需要使用旧版的轮询方法(-L)作为备选方案。
理解 Nodemon:开发环境 vs. 生产环境
nodemon 是一个专门用于本地开发的工具。它的目的是监视文件变化并重启应用,这在你积极编写和测试代码时非常有用,为开发者创造了一个快速、便捷的反馈循环。
然而,这种行为并不适合生产环境。Nodemon 的文件监视机制会增加不必要的资源开销,因为在生产环境中,代码不应该“随时”改变。在生产环境中,你不应该在服务器上修改文件并期望自动重启;变更应该通过结构化的部署流程来完成。如果你的生产应用因为未处理的异常而停止,nodemon 不会重启它,从而导致服务中断。
相反,生产服务器需要一个进程管理器,例如 PM2 或 systemd。进程管理器的工作是确保应用持续运行,它会在应用因错误而崩溃时自动重启,而不是在文件被修改时。进程管理器还处理其他生产环境的关键任务,如日志管理和以集群模式运行应用以提高性能。
第 1 步 — 安装 Nodemon
你可以通过两种方式安装 nodemon:全局安装到你的系统上,或作为项目的本地依赖。
全局安装
全局安装后,你可以在终端的任何目录中使用 nodemon 命令。
$ npm install -g nodemon
本地安装(推荐)
本地安装会将 nodemon 添加为你项目的 devDependency。这是推荐的方法,因为它将工具的版本与你的项目绑定在一起,确保团队中的所有开发者都使用相同版本的 nodemon。
$ npm install nodemon --save-dev
当你本地安装一个包时,你不能直接从命令行用 nodemon 来运行它。相反,你必须使用以下两种方法之一来运行:
- 使用
npx:npx命令随 npm 一起提供, 用于执行包。你应该运行npx nodemon。 - 使用 npm 脚本: 你可以将
nodemon添加到package.json文件的scripts部分。这是最常见和实用的方法,你将在接下来的步骤中使用它。
第 2 步 — 搭建一个 Express 示例项目
让我们创建一个小型的 Express 服务器来演示 nodemon 的工作方式。
首先,为你的项目创建一个新目录,进入该目录,并初始化一个新的 package.json 文件。
$ mkdir nodemon-demo
$ cd nodemon-demo
$ npm init -y
接下来,安装 express 作为依赖,并将 nodemon 作为开发依赖安装。
$ npm install express
$ npm install nodemon --save-dev
现在,在你的项目根目录中创建一个名为 server.js 的文件。
$ nano server.js
在你的文本编辑器中打开 server.js 并添加以下代码:
server.js
const express = require('express');
const app = express();
const port = 3000;app.listen(port, () => console.log(`Dolphin app listening on port ${port}!`))
这段代码创建了一个简单的 Express 服务器,它在端口 3000 上监听,并用一条消息响应根 URL (/) 的请求。
保存并关闭文件。
第 3 步 — 使用 Nodemon 运行你的应用
现在你有了一个服务器,你可以用 nodemon 来运行它。在项目中使用 nodemon 最有效的方法是将其添加到 package.json 的脚本中。
打开你的 package.json 文件。你会看到一个类似这样的 scripts 部分:
package.json
// ..."scripts": {"test": "echo \"Error: no test specified\" && exit 1"},// ...
修改 scripts 部分,添加两个新脚本:start 和 dev。
start:此脚本将使用node正常运行应用。这通常用于生产环境。dev:此脚本将使用nodemon运行应用。这用于开发环境。
package.json
// ..."scripts": {"start": "node server.js","dev": "nodemon server.js","test": "echo \"Error: no test specified\" && exit 1"},// ...
保存 package.json 文件。现在,你可以通过运行 dev 脚本在开发模式下启动你的服务器:
$ npm run dev
nodemon 将启动并包装你的 node 应用。你会看到类似以下的输出:
Output
[nodemon] 3.1.10
[nodemon] to restart at any time, enter `rs`
[nodemon] watching path(s): *.*
[nodemon] watching extensions: js,mjs,json
[nodemon] starting `node server.js`
Dolphin app listening on port 3000!
nodemon 报告说它正在监视所有文件 (*.*),并使用默认的扩展名 (.js, .mjs, .json)。
测试自动重载
在 nodemon 运行时,在新的终端中打开 server.js 文件并更改响应消息。
server.js
// ...
app.listen(port, () => console.log(`Shark app listening on port ${port}!`))
// ...
保存文件。当你回到终端时,你会看到 nodemon 已经自动检测到变化并重启了服务器。
Output
[nodemon] restarting due to changes...
[nodemon] starting `node server.js`
Shark app listening on port 3000!
第 4 步 — 使用命令行选项配置 Nodemon
你可以通过传递命令行选项来修改 nodemon 的行为。这些选项可以直接添加到 package.json 的 npm 脚本中。
以下是一些最常见的配置选项:
| 选项 | 描述 |
|---|---|
--watch <dir> | 指定一个或多个要监视的目录或文件。对多个路径使用多个 --watch 标志。 |
--ext <extensions> | 指定要监视的文件扩展名(例如,js,ts,json)。 |
--ignore <pattern> | 忽略特定的文件、模式或目录(例如,*.test.js, public/)。 |
--exec <command> | 执行一个不同的二进制文件而不是 node,例如用于 TypeScript 的 ts-node。 |
--delay <seconds> | 在重启前添加一个延迟(以秒为单位)。这可以“防抖”多个文件保存事件。 |
假设你正在开发一个 TypeScript 项目,并且你希望 nodemon:
- 只监视
src目录。 - 监视以
.ts结尾的文件。 - 忽略所有以
.test.ts结尾的测试文件。 - 使用
ts-node执行文件。
你在 package.json 中的 dev 脚本将如下所示:
package.json
// ..."scripts": {"dev": "nodemon --watch 'src' --ext 'ts' --ignore '*.test.ts' --exec 'ts-node' src/server.ts"},// ...
命令分解如下:
--watch 'src': 只监视src文件夹内的变化。--ext 'ts': 只监视扩展名为.ts的文件。--ignore '*.test.ts': 当测试文件改变时不重启。--exec 'ts-node': 使用ts-node二进制文件来运行文件,而不是node。src/server.ts: 应用的入口文件。
第 5 步 — 使用配置文件
命令行标志可能会变得很长且难以管理。一个更好的解决方案是使用配置文件。nodemon 会自动在你项目的根目录中寻找一个 nodemon.json 文件。
让我们为第 2 步中的 Express 项目创建一个配置文件。一个常见的需求是让 nodemon 监视 .env 文件(存储环境变量)的变化,或者忽略特定文件夹。
首先,在你项目的根文件夹中创建 nodemon.json 文件:
$ touch nodemon.json
现在,让我们配置它来:
- 明确监视
server.js文件和任何.env文件。 - 监视新的文件扩展名:
.js、.json和.env。 - 忽略
node_modules目录(尽管nodemon默认会这样做,但明确指出是个好习惯)。 - 在重启前添加 1 秒的延迟,以“防抖”多次快速保存。
打开 nodemon.json 并添加以下配置:
nodemon.json
{"watch": ["server.js",".env"],"ext": "js,json,env","ignore": ["node_modules/"],"delay": 1
}
有了这个文件,你的 package.json 脚本可以简化为:
package.json
// ..."scripts": {"start": "node server.js","dev": "nodemon","test": "echo \"Error: no test specified\" && exit 1"},// ...
现在,当你运行 npm run dev 时,nodemon 会找到并使用这些设置。如果你创建一个 .env 文件并进行更改,nodemon 将检测到它并重启服务器,这对于需要在启动时加载新环境变量的应用非常有用。
你也可以将此配置放在 package.json 文件中的 nodemonConfig 键下,但为了更好的组织,通常首选使用单独的 nodemon.json 文件。
第 6 步 — 手动重启
有时你可能需要强制重启你的应用,即使没有文件发生变化(例如,如果数据库连接丢失)。在 nodemon 运行时,你可以在终端中输入 rs 并按 ENTER 来手动触发重启。
[nodemon] manual restart
[nodemon] restarting due to changes...
[nodemon] starting `node server.js`
Dolphin app listening on port 3000!
第 7 步 — 解决常见问题
让我们看看在使用 nodemon 时可能遇到的一些常见问题。
错误:nodemon: command not found (命令未找到)
- 原因: 你本地安装了
nodemon(使用npm install nodemon --save-dev),但试图直接从终端运行nodemon server.js。你的 shell 不知道在哪里找到本地安装的二进制文件。 - 解决方案 1 (推荐): 通过 npm 脚本运行命令,如第 3 步所示(
npm run dev)。npm 脚本会自动查找本地安装的二进制文件。 - 解决方案 2: 使用
npx来执行本地包:npx nodemon server.js。 - 解决方案 3: 使用
npm install -g nodemon全局安装nodemon。
nodemon 在文件变化时没有重启
-
原因 1: 文件扩展名错误。 你正在保存一个
nodemon默认不监视的文件,例如.env或.sql文件。默认情况下,nodemon只监视.js、.mjs和.json。 -
解决方案 1: 使用
--ext标志或nodemon.json中的ext属性来添加你想要的扩展名。例如,要同时监视.env文件:nodemon.json
{"ext": "js,mjs,json,env" } -
原因 2: 文件路径被忽略。 你正在更改的文件位于一个被默认忽略(如
node_modules)或被你自己的配置规则忽略的目录中。 -
解决方案 2: 检查你的
nodemon.json文件中的ignore模式。 -
原因 3: 使用带有“安全写入”功能的编辑器。 一些文本编辑器和 IDE(如 JetBrains IDEs 或 Vim)使用“原子保存”或“安全写入”功能。此功能将更改保存到临时文件然后重命名它,这可能会干扰
nodemon使用的文件系统事件监听器。 -
解决方案 3: 使用
nodemon的“旧版监视”模式,通过添加-L标志。此模式会轮询文件变化,而不是依赖于文件系统事件。package.json
"scripts": {"dev": "nodemon -L server.js" },
应用在重启循环中崩溃
-
原因: 你启动
nodemon,它立即重启,一遍又一遍,而你没有更改任何文件。当你的应用有一个导致它在启动时立即崩溃的错误时,就会发生这种情况。nodemon看到进程退出,所以它重启它,结果应用再次崩溃,形成一个无限循环。Output [nodemon] starting `node server.js` /home/user/nodemon-demo/server.js:12app.listen(port, () => {^TypeError: app.listen is not a function [nodemon] app crashed - waiting for file changes before starting...在旧版本中,
nodemon可能会循环。在较新版本中(如上面的输出),nodemon通常足够智能,可以检测到这种情况,并会打印一条“app crashed”消息,并等待文件更改后再尝试。 -
解决方案: 仔细阅读终端中的错误消息。问题不在
nodemon,而在于你的应用代码。在示例输出中,错误是TypeError: app.listen is not a function。你必须修复server.js文件中的这个底层 bug。一旦你保存了修复,nodemon将检测到更改并正确重启应用。
高 CPU 使用率或重启缓慢
- 原因 1: 监视
node_modules。 默认情况下,nodemon配置为忽略node_modules目录。然而,nodemon.json中的错误配置(例如,一个不正确的watch路径意外地包含了node_modules)可能导致nodemon监视数千个文件,从而导致高 CPU 使用率。 - 解决方案 1: 确保你的
ignore模式是正确的。在你的nodemon.json中添加"ignore": ["node_modules/"]以明确指出。 - 原因 2: 旧版监视模式。 使用
-L(旧版监视)标志会强制nodemon轮询每个文件的更改,而不是使用操作系统的原生文件监视事件。这种效率要低得多,并且会显著增加 CPU 负载,尤其是在大型项目中。 - 解决方案 2: 只有在别无选择的情况下才使用
-L标志(例如,在有问题的虚拟机或容器环境中)。首先尝试修复底层的的文件系统事件问题,例如在你的文本编辑器中禁用“安全写入”。
常见问题解答
1. 在 Node.js 中,Nodemon 用来做什么?
Nodemon 是一个在本地开发期间使用的命令行工具,用于在检测到项目目录中的文件更改时自动重启你的 Node.js 应用。
它的主要目的是加快开发工作流程。默认情况下,当你对 Node.js 脚本进行更改时,你必须手动停止服务器(使用 Ctrl-C)并重新启动它(使用 node server.js)才能看到你的更改。Nodemon 会包装你的应用,监视文件修改,并自动为你处理这个重启过程。
2. 我如何全局安装和运行 Nodemon?
你可以使用带有 -g 标志的 npm 来全局安装 nodemon:
$ npm install -g nodemon
安装后,你可以通过将 node 命令替换为 nodemon,从终端的任何目录运行它:
$ nodemon app.js
虽然全局安装很方便,但推荐的方法是将 nodemon 作为开发依赖项在你的项目中本地安装。这可以确保项目上的所有开发人员都使用相同的版本。
$ npm install nodemon --save-dev
然后,你可以通过将其添加到 package.json 脚本中来运行本地版本:
package.json
"scripts": {"dev": "nodemon server.js"
}
然后使用以下命令运行它:
$ npm run dev
3. 为什么 Nodemon 没有自动重启我的应用?
这通常出于以下三个原因之一:
- 你正在编辑一个
nodemon不监视的文件扩展名。 默认情况下,nodemon只监视扩展名为.js、.mjs和.json的文件。如果你正在编辑像.env、.css或.sql这样的文件,nodemon将会忽略它。- 解决方案: 使用
--ext标志来指定你想要监视的所有扩展名。$ nodemon --ext "js,mjs,env,graphql" server.js
- 解决方案: 使用
- 你的文本编辑器正在使用“安全写入”或“原子保存”。 一些文本编辑器和 IDE(如 JetBrains 产品或 Vim)通过写入临时文件然后重命名它的方式来保存文件。这个过程可能会干扰
nodemon的文件系统事件监听器。- 解决方案: 使用
nodemon的旧版监视模式(-L),它会轮询更改而不是监听事件。$ nodemon -L server.js
- 解决方案: 使用
- 你正在更改的文件位于一个被忽略的目录中。
nodemon默认会忽略某些目录,例如node_modules/和.git/。如果你的文件位于一个自定义的忽略路径中,nodemon将不会重启。请检查你的nodemon.json配置中是否有任何ignore模式。
4. 我如何使用自定义的 Nodemon 配置文件?
你可以在项目的根目录中创建一个 nodemon.json 文件。nodemon 会自动找到并使用这个文件进行配置,这比使用冗长的命令行标志要清晰得多。
例如,与其使用这个命令:
$ nodemon --watch src/ --watch .env --ext "js,env" --delay 1`
你可以创建一个 nodemon.json 文件,内容如下:
nodemon.json
{"watch": ["src/",".env"],"ext": "js,env","delay": 1
}
现在,你只需运行 nodemon(或者 npm run dev,如果你使用 npm 脚本),它就会加载这些设置。
或者,你也可以将相同的配置直接添加到你的 package.json 文件中的 nodemonConfig 键下。
5. Nodemon 和 PM2 有什么区别?
主要区别在于它们的目标环境:nodemon 用于开发,而 PM2 用于生产。
nodemon在你保存文件时重启你的应用。它的目标是加快编码和测试速度。PM2是一个进程管理器,它在你的应用崩溃时重启它。它的目标是确保你的应用保持在线并对用户可靠。
这是一个并排比较:
| 特性 | nodemon (开发) | PM2 (生产) |
|---|---|---|
| 主要目标 | 开发者生产力。 | 应用正常运行时间和可靠性。 |
| 重启触发器 | 文件被修改或保存。 | 应用进程崩溃或服务器重启。 |
| 主要功能 | 文件监视、手动重启 (rs)。 | 崩溃恢复、集群、日志管理、启动服务。 |
6. 我可以在 TypeScript 或 ES 模块中使用 Nodemon 吗?
可以。对于 TypeScript,你需要告诉 nodemon 使用一个 TypeScript 执行引擎,如 ts-node 或 tsx。你可以通过 --exec 标志或配置中的 execMap 来实现。
这是一个 TypeScript 项目的 nodemon.json 示例:
nodemon.json
{"watch": ["src/"],"ext": "ts,json","exec": "ts-node src/server.ts"
}
对于 ES 模块(.mjs 文件或 package.json 中的 "type": "module"),nodemon 在现代版本的 Node.js 中可以自动工作。它默认监视 .mjs 文件,如果你使用 "type": "module",它将正确地将你的 .js 文件作为 ES 模块运行。
7. 我如何限制 Nodemon 监视哪些文件?
你可以使用 watch 和 ignore 配置来控制 nodemon 监视哪些文件。
watch: 这个选项指定nodemon应该 监视哪些目录或文件。默认情况下,它监视当前目录 (.)。如果你指定了一个watch路径,它将只监视那个路径。ignore: 这个选项指定要从监视中排除的文件或模式。nodemon默认忽略node_modules/和.git/。
你可以在 nodemon.json 文件中使用这些来进行精确控制。例如,如果你希望 nodemon 只监视你的 src/routes 目录和你的 .env 文件,但忽略该目录下的所有测试文件:
nodemon.json
{"watch": ["src/routes/",".env"],"ignore": ["*.test.js"],"ext": "js,env"
}
结论
nodemon 是一个简单的工具,它显著改善了 Node.js 的开发体验。通过自动化服务器重启过程,它消除了一个繁琐的手动步骤,让你能够专注于编写代码。
在本教程中,你学习了 nodemon 是如何通过监视文件系统来工作的,如何安装它,以及如何使用 npm 脚本来运行 Node.js 应用。你还使用命令行标志和 nodemon.json 配置文件来配置其行为。此外,你还探讨了开发中使用的 nodemon 与生产中使用的进程管理器之间的关键区别,并学会了如何解决常见问题。
要了解所有可用功能的更多信息,你可以查阅官方 nodemon 文档。
