根本原因是vscode调试器默认不附加vitest worker线程,必须在launch.json中显式配置"autoattachchildprocesses": true,否则断点失效、日志不全、cpu飙升;同时需避免ts-node等非标准启动方式,并合理设置pool策略与skipfiles。

VSCode 里 Vitest 多线程测试跑不起来、速度没提升,甚至直接报错或断点失效——根本原因不是 Vitest 配置太复杂,而是 Node 环境和 Vitest 的并发模型被混为一谈:Vitest 的 threads: true(默认开启)跑的是 worker 并行,但 VSCode 调试器不自动 attach 这些 worker,且若 Node 本身未启用子进程调试支持,连启动都失败。
为什么 vitest --threads 在 VSCode 里不生效
Vitest 默认启用多线程(threads: true),但它依赖底层 Node.js 的 Worker 实例;而 VSCode 的 JavaScript Debug Terminal 或“Debug Test”按钮,默认只 attach 主进程,完全忽略 worker 线程。结果就是:测试看似在跑,但断点全跳过、覆盖率统计不准、console.log 只打主进程输出。
- 验证方式:终端手动运行
vitest --no-file-parallelism --test-timeout=0,如果断点能停住,说明问题出在并行模式而非代码本身 -
--threads和--no-file-parallelism是正交开关:前者控制单个 test 文件内是否用 worker 拆分 it 块,后者控制多个 test 文件是否并行执行——你常想开的是前者,但 VSCode 调试器只认后者关掉后的单进程流 - 若项目含
vi.mock()或动态import(),worker 线程可能因模块解析失败直接退出,错误被静默吞掉,表现为“测试没运行”
launch.json 必须加 autoAttachChildProcesses: true
这是让 VSCode 真正感知 Vitest worker 的唯一可靠方式。它不是可选项,是开关。没有它,VSCode 根本不知道有子线程存在。
使用一条命令部署ProbeChain Rydberg测试网代理节点。自动注册为Agent(NodeType=1),免gas,支持macOS/Linux/Windows。触发词:/r
- 配置位置:
.vscode/launch.json中任一configuration下,必须显式写"autoAttachChildProcesses": true - 仅对
new Worker()和child_process.fork()生效;spawn()需额外加--inspect-brk才被识别 - 若你用
ts-node或esbuild-node启动 Vitest(比如通过npm run test:debug),此配置会失效——因为它们绕过了标准 Node 启动链,必须改用原生node -r ts-node/register node_modules/vitest/vitest.mjs方式 - macOS/Linux 下用 nvm 时,还需补
"runtimeExecutable": "/path/to/node",否则子进程可能用错 Node 版本
vitest.config.ts 中的 threads 与 pool 怎么选
Vitest 2.x+ 把并发策略拆得更细:threads 控制是否启用 worker,pool 决定用哪套底层调度器。盲目开 threads: true 可能反而变慢。
- 纯同步逻辑(如工具函数、DTO 验证):开
threads: true+pool: 'threads',提速明显 - 含 I/O 或外部依赖(如数据库 mock、HTTP 调用):关
threads,改用pool: 'forks',避免 worker 间资源争抢 - TypeScript 项目务必配
typecheck: { enabled: false },否则每个 worker 都会重复启动 TS 类型检查服务,CPU 直接拉满 - 若测试中用了顶层 JSX 或
defineComponent,但没注册@vitejs/plugin-vue,worker 启动即报ReferenceError,日志里只显示 “worker exited with code 1”,需查vitest --reporter verbose输出定位
VSCode 调试时 CPU 飙升、卡死的硬止损法
不是 Vitest 太重,是 VSCode 调试器在索引所有 worker 加载的模块路径(尤其 node_modules)。不干预就会卡在 100% CPU。
- 在
launch.json每个 configuration 中强制加:"skipFiles": ["<node_internals>/**", "**/node_modules/**"]</node_internals> - 禁用
"trace": true和"autoAttach": "always",这两项会触发高频堆快照采集,对长周期测试极不友好 - 真正稳定的做法:用命令行启动
node --inspect-brk=9229 node_modules/vitest/vitest.mjs,再在 VSCode 里用"request": "attach"连接——绕过 launch.json 初始化阶段的所有文件扫描 - 别信
--max-old-space-size写在runtimeArgs里就能生效;它只影响主进程,worker 线程内存由Worker构造时的resourceLimits控制,Vitest 不暴露该配置,实际只能靠减少单个 test 文件体量来规避 OOM
最易被忽略的一点:Vitest 的 worker 并行和 Node 的 cluster 模块无关,也和 child_process.fork() 的多进程部署无关。你在 VSCode 里看到的“多线程”只是 Vitest 自己用 Worker API 模拟的轻量级并发,它共享同一份 V8 堆,但调试器视角里仍是独立进程——所以 autoAttachChildProcesses 这个开关,漏掉就等于没配。










