Dev Server重复重启触发EADDRINUSE错误,nodemon异常求助
我太懂这种每次要手动杀进程的烦躁了!你遇到的问题本质是nodemon重启时没彻底干掉旧的服务器进程,导致旧进程还占着8081端口,新进程启动就撞端口报错。下面给你一步步排查和解决的方案:
一、先升级nodemon(最优先!)
你用的是1.19.4版本,这是好几年前的旧版本了,当时nodemon在进程管理上确实存在一些bug。赶紧升级到最新版:
# 全局升级 npm install -g nodemon@latest # 如果是项目本地依赖,就用这个 npm install nodemon@latest --save-dev
很多时候升级完这个问题直接就消失了。
二、给你的服务器代码加上信号处理逻辑
Node.js进程默认不会自动响应终止信号(比如nodemon重启时发送的SIGTERM,或者你按Ctrl+C触发的SIGINT),导致进程没真正退出,端口一直被占用。你需要在server.js里加上这段代码,确保进程能优雅关闭:
// 假设你用的是Express,其他框架逻辑类似 const express = require('express'); const app = express(); // 把server实例存下来,方便后续关闭 const server = app.listen(8081, () => { console.log('> Ready on http://localhost:8081'); }); // 监听SIGTERM信号(nodemon重启时会发送这个) process.on('SIGTERM', () => { console.log('收到终止信号,正在优雅关闭服务器...'); server.close(() => { console.log('服务器已关闭'); process.exit(0); // 彻底退出进程 }); }); // 监听SIGINT信号(Ctrl+C时触发) process.on('SIGINT', () => { console.log('收到中断信号,正在优雅关闭服务器...'); server.close(() => { console.log('服务器已关闭'); process.exit(0); }); });
这样nodemon重启时,旧进程会主动关闭服务器、释放端口,不会再和新进程抢端口了。
三、检查nodemon的watch配置,避免无限重启循环
如果nodemon监听了会被服务器自身修改的文件(比如日志文件、上传的静态文件、甚至是编译后的输出文件),就会触发无限重启:改文件→重启→服务器再改文件→再重启... 旧进程根本来不及退出,端口就被占了。
解决方法是创建一个nodemon.json配置文件,明确指定要监听的源码文件,排除动态生成的文件:
{ "watch": ["server.js", "routes/", "controllers/"], // 只监听你的业务源码目录 "ignore": ["node_modules/", "logs/", "uploads/", "dist/"], // 排除依赖、日志、编译产物等 "ext": "js,mjs,json" }
启动时用这个配置:
nodemon --config nodemon.json server.js
四、终极暴力方案:强制杀死旧进程
如果上面的方法都没效果,可以让nodemon用SIGKILL信号强制杀死旧进程(相当于手动执行kill -9):
nodemon --kill-signal SIGKILL server.js
不过这个是下策,尽量先解决根本问题,毕竟暴力杀进程可能会导致数据丢失(比如未写入的日志)。
五、偷懒小技巧:一键杀端口
如果偶尔还是会遇到端口占用,你可以在package.json里加个脚本,一键清理端口:
{ "scripts": { "start": "nodemon server.js", "kill-port": "sudo lsof -t -i :8081 | xargs sudo kill -9" } }
需要的时候直接执行npm run kill-port就行,不用手动敲一大串命令。
内容的提问来源于stack exchange,提问作者Sean D

