利用 vscode 调试代码时,launch
里面有个配置request:launch/attach
,今天就来盘一盘这两个配置的区别。
"configurations": [
{
"name": "debug nestjs",
"request": "launch",
"args": ["run", "start:dev"],
"runtimeExecutable": "npm",
"skipFiles": ["<node_internals>/**"],
"type": "node"
},
{
"name": "Attach by Process ID",
"processId": "${command:PickProcess}",
"request": "attach",
"skipFiles": [
"<node_internals>/**"
],
"type": "node"
}
]
先来看看它们的字面意思:
Launch(启动)模式
当你使用 launch
模式进行调试时,VSCode 将直接启动并控制你想要调试的应用程序。
这意味着 VSCode 会作为应用程序的启动器,它会在内部创建一个进程来运行你的代码,并且这个进程会受到调试器的监控。
当你在代码中设置了断点,程序在运行到这些断点时会暂停,等待你进行调试操作,比如单步执行、查看变量值等。
Attach(附加)模式
相比之下,attach
模式允许你将调试器连接到一个已经运行的外部进程。
比如,我们在调试nodejs项目时,有时候也会用chrome浏览器的调试界面来调试,如下图:
这通常用于调试那些不能由 VSCode 直接启动的程序,或者你想在程序运行到某个特定状态时才开始调试的情况。
在 attach
模式下,你需要先手动启动你的应用程序,然后配置调试器去连接到该应用程序的进程ID或监听的端口。
一旦连接成功,你就可以像在 launch
模式下那样设置断点和进行调试。
在上一篇文章中《nestjs系列二:如何优雅调试nestjs》(juejin.cn/post/738796… nestjs 项目,本文我将详细介绍attach
模式调试 nestjs 项目。
讲attach
模式之前,我们需要简单的了解下调试原理。
调试一般分为两部分:backend 和 frontend。
对于Chrome DevTools
来说:
- backend: 它和 Chrome 集成在一起,负责把 Chrome 的网页运行时状态通过调试协议暴露出来。
- frontend: 它是独立的,负责对接调试协议,做 UI 的展示和交互。
两者之间的调试协议叫做 Chrome DevTools Protocol。
简单来说,调试就是把frontend界面启动,这时候会有一个backend的 WebSocket 的调试服务,我们用 frontend 的 WebSocket 客户端连接上这个 WebSocket 服务,就可以进行调试了。
对于VSCode Debugger
, 它的原理和 Chrome DevTools 差不多,也是分为 frontend、backend、调试协议这几部分,只不过它多了一层适配器协议。
因为 VSCode 不是 JS 专用编辑器,它可能用来调试 Python 代码、Rust 代码等等,自然不能和某一种语言的调试协议深度耦合,所以多了一个适配器层。
VSCode Debugger 的 UI 的部分算是 frontend,而调试的目标语言算是 backend 部分,中间也是通过 WebSocket 传递调试协议。
所以,你如果用attach
模式进行调试,首先要启动服务,同时要启动一个ws服务,我们执行nestjs提供的调试命令nest start --debug
:
可以看到,它启动了一个ws服务和一个nestjs服务,然后配置launch.json
:
{
"version": "0.2.0",
"configurations": [
{
"name": "Attach",
"port": 9229,
"request": "attach",
"skipFiles": ["<node_internals>/**"],
"type": "node"
}
]
}
点击左上角的调试按钮,启动调试,也就是把frontend启动起来,它就会根据配置文件launch.json
去链接到ws服务上的9229端口。
这样就完成了attach
模式下调试nestjs
服务。
总之,launch
模式就是vscode直接帮你启动了你要调试的服务和调试器,并把它们链接起来,不需要你操心了。
attach
模式需要你自己启动服务和ws服务,然后再启动调试器,这适用于已经启动的服务,需要中途进行调试。