使用nodemon搭配babel-node时终端崩溃但服务器正常运行
问题背景
你配置了这样的package.json启动命令:
"open-graph-playground": "nodemon --exec babel-node src/graphql/mock-server.js"
运行yarn open-graph-playground后终端抛出错误:
yarn run v1.13.0
$ nodemon --exec babel-node src/graphql/mock-server.js
[nodemon] 1.18.10
[nodemon] to restart at any time, enterrs
[nodemon] watching: .
[nodemon] startingbabel-node src/graphql/mock-server.js
2019-05-30 15:45 node[1683] (FSEvents.framework) FSEventStreamStart: register_with_server: ERROR: f2d_register_rpc() => (null) (-22)
2019-05-30 15:45 node[1683] (FSEvents.framework) FSEventStreamStart: register_with_server: ERROR: f2d_register_rpc() => (null) (-22)
[nodemon] Internal watch failed: EMFILE: too many open files, watch error
Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
还出现了奇怪的现象:终端进程已经终止,但http://localhost:4001/mock-graphql-playground上的服务器仍在正常运行。
问题原因
- 文件打开数超限:nodemon默认监听所有文件(
*.*),加上babel-node编译过程中会打开大量文件,超过了系统默认的文件打开上限,触发EMFILE错误。日志里的FSEvents相关报错也说明这是macOS系统下的文件监听资源不足问题。 - 子进程未被终止:当nodemon因监听失败崩溃时,没有正确终止由
babel-node启动的服务器子进程,导致服务器继续在后台运行。
解决方案
1. 缩小nodemon的监听范围(最优先推荐)
别让nodemon监听所有文件,只关注项目中需要热更新的文件类型(比如.js、.graphql),大幅减少监听负载:
修改package.json命令:
"open-graph-playground": "nodemon --watch src --ext js,graphql --exec babel-node src/graphql/mock-server.js"--watch src指定只监听src目录,--ext js,graphql限定监听的文件后缀。创建nodemon.json配置文件:
在项目根目录新建nodemon.json:{ "watch": ["src"], "ext": "js,graphql", "exec": "babel-node src/graphql/mock-server.js" }然后package.json命令简化为:
"open-graph-playground": "nodemon"
2. 提高系统的文件打开限制(macOS)
如果缩小监听范围后仍有问题,可以临时或永久提高系统文件打开上限:
- 临时生效(当前终端会话有效):
ulimit -n 10240 - 永久修改(需重启系统):
编辑/etc/limits.conf(无则新建),添加:
重启系统后生效。* soft nofile 10240 * hard nofile 10240
3. 确保nodemon崩溃时终止子进程
添加--exitcrash参数,让nodemon崩溃时强制终止所有子进程:
"open-graph-playground": "nodemon --exitcrash --watch src --ext js,graphql --exec babel-node src/graphql/mock-server.js"
这样就不会出现终端进程终止但服务器还在运行的情况了。
内容的提问来源于stack exchange,提问作者Evanss

