ts-node调试需配置runtimeargs为["--nolazy", "-r", "ts-node/register"],支持断点映射;若启用esm则改用"--loader=ts-node/esm";tsconfig中仅"moduleresolution"和"resolvejsonmodule"生效,其余如sourcemap、outdir等无效。

launch.json 里 runtimeArgs 必须包含 ts-node/register
VSCode 调试器本身不认识 .ts 文件,它只懂 Node.js 的 JS 运行时。想让断点打在 .ts 上,就得靠 ts-node 在启动时注入转译逻辑——这一步全靠 runtimeArgs 驱动。
常见错误是只写了 "runtimeExecutable": "npx" 或漏掉 -r 参数,结果调试器直接报 Cannot find module 'xxx' 或断点显示“未绑定”。
-
"runtimeExecutable": "node"(不是npx或ts-node) -
"runtimeArgs": ["--nolazy", "-r", "ts-node/register"]——--nolazy确保源码提前加载,-r是关键入口 -
"args": ["${workspaceFolder}/src/index.ts"],别用program字段指向.ts,那是给纯tsc编译流用的 - 如果项目用了
"type": "module",必须加--esm:把"-r"换成"--loader=ts-node/esm"(Node.js ≥18.12)
tsconfig.json 的 sourceMap 和 outDir 不影响 ts-node 调试
ts-node 是内存中转译,不落地 .js 和 .js.map 文件,所以 tsconfig.json 里设了 "sourceMap": true 或 "outDir" 对它没用——这些只对 tsc 编译生效。
但有两点必须配:
-
"moduleResolution": "node"(或"node16"/"nodenext"),否则路径别名(如@/utils)无法解析 -
"resolveJsonModule": true,否则import pkg from './package.json'会报错 - 如果用了
baseUrl+paths,ts-node会读,但不会做路径重写;确保tsconfig.json存在且合法,否则它可能静默降级为默认行为
断点失效?先检查 VSCode 是否用了 workspace 版本 TS
右下角状态栏显示的 TypeScript 版本,只是语言服务(语法提示、跳转)用的;而 ts-node 运行时完全依赖你 node_modules 里的包。两者版本不一致,就会出现“编辑器里没红波浪线,一调试就 TS2307 找不到模块”。
解决方法很直接:
- 右下角点击 TypeScript 版本号 → 选 Use Workspace Version
- 确认项目已装
typescript和ts-node:npm install --save-dev typescript ts-node @types/node - 改完
tsconfig.json后,按Ctrl+Shift+P→ 输入TypeScript: Restart TS server,否则旧缓存会让断点映射错位
想边调试边报类型错误?别信默认行为
ts-node 默认只做语法转译,any 泛滥、属性未定义、类型不匹配……统统不报。你以为代码跑通了,其实只是被静默绕过了。
要强制类型检查,必须显式加参数:
-
--files:让ts-node读取整个include范围,而不是只处理入口文件 -
--no-cache:避免缓存导致类型错误不刷新 - 组合起来就是:
"runtimeArgs": ["--nolazy", "-r", "ts-node/register", "--files", "--no-cache"] - 注意:这会让启动变慢,尤其大项目;日常开发可先关掉,CI 或提交前用
npx tsc --noEmit补检
最常被忽略的是:ts-node 的调试链路完全不经过 tsc,所以你在 tsconfig.json 里配的 "incremental"、"composite"、"extends" 全部无效。它只认基础字段,别的都是摆设。











