根本原因是VS Code调试配置未适配TypeScript,需用ts-node执行并启用sourceMap;热重载需nodemon监听全路径;接口连不上常因端口占用或.env未加载;Hook断点失效多因注册顺序错误或匿名函数内联。

FeathersJS 后端项目在 VS Code 中跑不起来、热重载失效、调试断点不触发——根本原因不是框架难,而是 VS Code 没配对运行时和调试链路。Node.js + TypeScript + Feathers 的组合下,nodemon 和 ts-node 必须协同工作,且不能依赖默认的 node 直接执行 src/index.ts。
为什么直接 F5 调试会报错“Cannot find module 'src/index.ts'”
VS Code 默认调试器只认 JavaScript,不处理 TypeScript 编译。即使你有 tsconfig.json,launch.json 若没指定 runtimeExecutable 和 runtimeArgs,它就会尝试用原生 node 去加载 .ts 文件,自然失败。
- 错误典型现象:
internal/modules/cjs/loader.js:905 throw err; Error: Cannot find module './src/index.ts' - 正确做法:让调试器调用
ts-node(或nodemon --exec ts-node)作为入口执行器 - 必须确保已安装:
npm install -D ts-node @types/node nodemon -
launch.json关键字段示例:
{
"version": "0.2.0",
"configurations": [
{
"type": "node",
"request": "launch",
"name": "Launch Feathers (ts-node)",
"runtimeExecutable": "npx",
"runtimeArgs": ["ts-node", "--project", "./tsconfig.json", "./src/index.ts"],
"console": "integratedTerminal",
"skipFiles": ["<node_internals>/**"]
}
]
}</node_internals>
如何让保存即重载、实时看到 Feathers 服务变化
Feathers 本身不自带热重载,得靠 nodemon 监听文件变化并重启进程。但默认配置容易漏掉 src/ 下的 service、hook、model 等子目录,导致改了 hook 却没生效。
- 检查
nodemon.json是否存在,内容应包含完整监听路径:
{
"watch": ["src/**/*", "config/**/*", ".env"],
"ext": "ts,json,js",
"ignore": ["src/**/*.spec.ts", "node_modules/"]
}
- 启动命令建议统一用:
npm run dev,对应package.json中:
"scripts": {
"dev": "nodemon --config nodemon.json"
}
- 别用
ts-node src/index.ts手动跑——它不监听,也不清理旧 socket 连接,多次 Ctrl+C 后端口常被占住
REST Client 或 Thunder Client 测试接口时连不上 localhost:3030
不是后端没启,而是 VS Code 终端里运行的进程可能被意外终止,或者环境变量(比如 .env)没加载进当前 shell。
- 确认终端是否在项目根目录下运行:
npm run dev,而非某个子文件夹 - 检查
.env文件是否被dotenv正确读取:Feathers 默认用@feathersjs/configuration,需确保src/index.ts中有类似app.configure(configuration()) - 在 REST Client 中写请求时,务必加
Content-Type: application/json,否则 Feathers 的json()parser 可能跳过 body 解析 - 常见连接拒绝错误:
connect ECONNREFUSED ::1:3030→ 先在终端执行lsof -i :3030(macOS/Linux)或netstat -ano | findstr :3030(Windows)看端口是否真被占用
调试 Feathers Hook 时断点不命中
Hook 是函数式中间件,若你在 src/hooks/my-hook.ts 里打了断点却从不暂停,大概率是 Hook 没被注册进服务链,或注册时机不对。
- 确认 Hook 注册位置:必须在
app.use('/messages', messages)之后,再调用messages.hooks(...),顺序反了就无效 - TS 调试时,确保
sourceMaps开启:在tsconfig.json中设"sourceMap": true,且launch.json不要设"sourceMaps": false - 避免在匿名函数里打断点,例如:
context => { debugger; ... }—— 某些 TS 编译模式下会被内联或丢弃,改用具名函数更稳 - 如果用的是
@feathersjs/express,记得app.use(express.json())和express.urlencoded()在所有服务注册之前,否则context.data为空
最易忽略的一点:Feathers 的 app.listen() 返回的是原生 http.Server 实例,不是 Promise。如果你在 src/index.ts 里写了 await app.listen(port),TS 不报错但运行时会卡住——这里没有 async 的必要,直接 app.listen(port) 即可。











