终端分栏是同时运行前后端的最直接可控方式:按Ctrl+`开终端并cd至后端目录运行node api/server.js,再Ctrl+\分栏运行node app.js,两进程独立响应Ctrl+C;tasks.json需设isBackground、dependsOn+parallel、显式cwd和dedicated面板;concurrently更可靠,支持跨平台、统一终止与日志前缀;调试需用compounds组合独立配置,避免端口冲突。

终端分栏是最直接、最可控的方式
想一边跑 node app.js,一边跑 node api/server.js,别点右键“在终端中运行代码”,也别写个 && 或 & 拼命令——那只是 shell 串行或不可控后台,VSCode 根本不感知进程状态,Ctrl+C 传不进子进程,日志还挤在一起。
正确做法是用原生分栏:
- 按
Ctrl+`打开第一个终端,cd到后端目录,运行node api/server.js - 右键该终端标签 → 选
Split Terminal(或按Ctrl+\),得到第二个终端面板 - 新面板默认继承上一个的工作目录,如果它不是你要的路径,先
cd过去,再运行node app.js - 两个进程完全独立:各自有 PID、各自占端口、各自响应 Ctrl+C
注意:terminal.integrated.splitCwd 默认是 inherit,不是 workspaceRoot。如果你刚在某个子目录里执行过 cd,新分栏也会从那里开始——容易误进错目录导致模块找不到。
tasks.json 并行配置适合需要复用和触发的场景
你希望每次按 Ctrl+Shift+P → Tasks: Run Task → 选 Run Full Stack 就同时拉起前后端?那就得配 tasks.json,但必须避开几个硬坑:
- 每个子任务必须设
"isBackground": true,否则第二个任务会卡住等第一个退出 - 靠
"dependsOn": ["backend", "frontend"]+"runOptions": { "parallel": true }实现并发,不是只写dependsOn就自动并行 -
"options": { "cwd": "${workspaceFolder}/backend" }必须显式写,否则两个任务都在项目根目录下执行,require('./config')可能读错文件 - 加
"presentation": { "panel": "dedicated" },否则所有输出都堆在同一个终端面板里,日志混成一团
不推荐用 shell 类型任务直接写 npm run dev & npm run api:Windows 不认 &,且 VSCode 无法 kill 子进程,关终端后 node.exe 常驻后台吃 CPU。
concurrently 是真正可靠的一键方案
当你的需求超出“手动分栏”或“简单双任务”,比如要统一控制退出、带颜色前缀、失败时全杀、还要兼容 Windows,就别硬扛了,上 concurrently:
- 先装依赖:
npm install --save-dev concurrently - 在
package.json里加脚本:"dev:all": "concurrently -k -n \"BE,FE\" \"npm run dev:be\" \"npm run dev:fe\"",其中-k表示任一崩溃则全部终止,-n给每条日志打前缀,避免混淆 - VSCode 任务只需调一条:
"command": "npm run dev:all",并确保"isBackground": true
concurrently 启动的是真实子进程,不是 shell 封装,所以 Ctrl+C 能透传,调试器也能 attach 上;它还会自动分配不同 TTY,比裸写 npm run a & npm run b 稳定得多。
调试多个 Node.js 应用不能靠一个 launch.json 配置
你以为在 launch.json 里写两个 "type": "node" 就能一起 Debug?不行。VSCode 的 configurations 数组是顺序执行,且只启动第一个;真要同时调试,必须用 compounds:
- 每个服务单独定义一个
configuration,name唯一(如"Frontend"、"Backend"),port不能重复(比如9229和9230) - 每个都设
"console": "integratedTerminal",否则第二个会卡住不动 - 在
compounds里组合:{"name": "Full Stack", "configurations": ["Frontend", "Backend"]} - 务必确认
"request": "launch"(不是attach),且program路径真实存在——TS 项目尤其容易因outFiles或preLaunchTask缺失导致断点不命中
端口冲突是最常被忽略的点:没手动指定 port,两个服务都试图监听 9229,第二个必然报 Cannot connect to the target,连启动日志都不会输出。


















