New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

VSCode 调试 Egg 完美版 - 进化史 #25

Open
atian25 opened this Issue Feb 8, 2018 · 43 comments

Comments

Projects
None yet
@atian25
Copy link
Owner

atian25 commented Feb 8, 2018

背景

VSCode 早期版本,对 Node Cluster 的调试支持一直不是很友好,譬如:

  • 开发期重启进程后,不支持重新 attach。
  • Cluster 重启后 debugPort 会自增,VSCode 也不支持 attach 新端口。
  • Egg 的 多进程模型 多了 Agent 处理公关事务,在开发期也有 3 个进程(master, agent, worker)。

那些折腾过的历史

黑暗时代

早在 2016 年时就开始的折腾:#14#15 ,没有太好的办法。

青铜时代

然后 @okoala 写了 egg-development-proxyworker

主要思路是在 agent 里面启动一个 socket proxy 来动态代理 worker 的调试端口。
很巧妙的解决了自动重启后调试端口变化问题,但缺点是要开发者手动安装插件,并配置 vscode。

此时只能说达到可用的阶段。

黄金时代

接着,我写了 egg-bin debug 把 proxy 功能内置了,实现原理参见当时的 RFC 提案

并且提供了 vscode-eggjs 扩展来方便配置。

解决了:

  • 自动 attach 重启后的 worker 新端口
  • 自动生成 launch.json

对于一般应用开发者基本上已经非常易用了,但还存在以下问题:

  • vscode 的 launch.json 对同时 attach 多个的支持不是很友好,虽然有 compounds
  • 默认只 attach worker,并且不支持启动期的断点,如果要 brk 的话要手动 attach 3 次,非常麻烦。

而今天,VSCode@1.12.0 正式支持了 Automatically attach debugger to Node.js subprocesses

因此我们之前的做法可以大幅简化了,没解决的问题也基本解决了,可以称为 完美版 了。

完美版的人生

文档已经更新:使用 VSCode 进行调试

安装 vscode-eggjs,并初始化调试配置(如果之前有则需删除 launch.json 文件)

image

然后简单的一个 F5 搞定~

简析

// .vscode/launch.json
{
  "version": "0.2.0",
  "configurations": [
    {
      "name": "Launch Egg",
      "type": "node",
      "request": "launch",
      "cwd": "${workspaceRoot}",
      "runtimeExecutable": "npm",
      "windows": { "runtimeExecutable": "npm.cmd" },
      // 启动我们的 egg-bin debug 并默认是 brk
      "runtimeArgs": [ "run", "debug", "--", "--inspect-brk" ],
      // 日志输出到 Terminal,否则启动期的日志看不到
      "console": "integratedTerminal",
      "protocol": "auto",
      // 进程重启后自动 attach
      "restart": true,
      // 因为无需再 proxy,故改回原来的 9229 端口
      "port": 9229,
      // 自动 attach 子进程 
      "autoAttachChildProcesses": true
    }
  ]
}

其他

vscode 扩展生成的配置里面,还支持了单元测试的断点,配置如下:

{
  "version": "0.2.0",
  "configurations": [
    {
      "type": "node",
      "request": "launch",
      "name": "Egg Test",
      "runtimeExecutable": "npm",
      "runtimeArgs": [
        "run",
        "test-local",
        "--",
        "--inspect-brk"
      ],
      "protocol": "auto",
      "port": 9229,
      "autoAttachChildProcesses": true
    }
  ]
}

完美版.最终版1

VSCode 1.22 支持了 Automatically Attach to Node.js processes,也就是如果你开启了这个的话,无需配置什么 launch.json,直接在 terminal 执行 npm run debug --inspect-brk 就会自动 attach 了。

补充

Egg 的调试,跟 Node 没啥区别,因此一定要了解 Node 的基础调试知识。

其中,--inspect-brk 是指在进程第一行就暂停,等待 attach,因此:

  • master 先启动,在第一行会停住,需要你 attach master,才会往下走
  • 接着 master 启动 agent,也是在第一行停住,需要 attach agent 才会往下走
  • 最后 agent 启动完成后,worker 才开始启动,一样也是在第一行停住,需要 attach agent 才会往下走

上面这几个 attach,由于上面我们提到的 VSCode 的支持,只需要开启配置,即可无感知的一键 attach。
虽然如此,但作为开发者,大家还是需要理解 Node 的调试原理。

@atian25 atian25 changed the title VSCode 调试 Egg 完美版 VSCode 调试 Egg 完美版 - 进化史 Feb 8, 2018

@atian25

This comment has been minimized.

Copy link
Owner Author

atian25 commented Feb 8, 2018

TODO: 补充 egg cluster 背景,重启时消息流向图(messenger, debug)

                  +--------+
                  | Parent |  (egg-scripts/egg-bin)
                  +--------+
                      | 
                      | 
                      v
                  +--------+           +-------+
                  | Master | --------> | Agent |
                  +--------+           +-------+
                 /    |     \
               /      |       \
             /        |         \
           v          v          v
  +----------+   +----------+   +----------+
  | Worker 1 |   | Worker 2 |   | Worker 3 |
  +----------+   +----------+   +----------+
@atian25

This comment has been minimized.

Copy link
Owner Author

atian25 commented Feb 11, 2018

先删除原有的 .vscode 文件

kapture 2018-02-09 at 11 27 33

@zxmajunhong

This comment has been minimized.

Copy link

zxmajunhong commented Mar 15, 2018

在启动调试之前,我先需要执行npm run debug 吗?

@atian25

This comment has been minimized.

Copy link
Owner Author

atian25 commented Mar 15, 2018

不需要,你去看下 vscode 自己的调试指南就懂了

@my9074

This comment has been minimized.

Copy link

my9074 commented Mar 28, 2018

@atian25 我安装了 vscode-eggjs 在 DEBUG 模式,没有对应的 EGG 选项。
环境都是最新版的。
mar-28-2018 16-03-02

@atian25

This comment has been minimized.

Copy link
Owner Author

atian25 commented Mar 28, 2018

vscode 的激活时机好像有问题,你试下随便打开一个 js,输入下 egg

image

能看到这个的话,再回去调试页面看看

@my9074

This comment has been minimized.

Copy link

my9074 commented Mar 28, 2018

@atian25 EGG 选项出来了,但是 configurations 是空的。
mar-28-2018 16-48-46

@atian25

This comment has been minimized.

Copy link
Owner Author

atian25 commented Mar 28, 2018

那可能是 vscode 这块的 API 变了。
手动拷贝下我上面贴的 config 吧

@shepherdwind

This comment has been minimized.

Copy link

shepherdwind commented Apr 4, 2018

npm run test-local 支持测试单个文件吗?

@atian25

This comment has been minimized.

Copy link
Owner Author

atian25 commented Apr 4, 2018

支持, npm run test-local -- --grep= 支持所有的 mocha 参数,可以看下 egg-bin 的 READM

@atian25

This comment has been minimized.

Copy link
Owner Author

atian25 commented Apr 4, 2018

或者 npx egg-bin test --grep=

@atian25

This comment has been minimized.

Copy link
Owner Author

atian25 commented Apr 6, 2018

VSCode 1.22 新增 Auto Attach 功能,在 Terminal 里面 npm run debug 后,会自动 attach,不需要你 F5 或上面那堆 launch.json 配置啥的

@caohongtao

This comment was marked as outdated.

Copy link

caohongtao commented Apr 10, 2018

image
Egg Debug启动的时候,会报This socket has been ended by the other party错误。昨天升级新vscode后出现的。
然而,先手动执行egg-bin debug,然后使用Egg Attach to remote,可以正常attach上去。

@atian25

This comment was marked as outdated.

Copy link
Owner Author

atian25 commented Apr 10, 2018

vscode 新版的 bug,暂时还没时间看,需要跟 vscode 那边反馈

@wangtao0101

This comment was marked as outdated.

Copy link

wangtao0101 commented Apr 13, 2018

vscode 新版无法调试,先手动执行egg-bin debug,然后使用Egg Attach to remote,虽然正常attach上去了,但是无法打断点。。。

@wangtao0101

This comment was marked as outdated.

Copy link

wangtao0101 commented Apr 13, 2018

@caohongtao 你是用的typescript吗?attach后能打断点吗?

@StephenSeraph

This comment has been minimized.

Copy link

StephenSeraph commented Apr 14, 2018

几个月以来我都是用的下面这套配置,包括最近的ts版本,调试体验良好。
也试过最新的官方推荐配置和Auto Attach 方式,都不太好用。本着有保底的办法、外加偷懒的心态,也就没深究了😅
这个配置其实就是之前某个版本的eggjs vscode插件的配置写法,有需要的同学可以参考一下,希望有帮助。

{
  "version": "0.2.0",
  "configurations": [
    {
      "type": "node",
      "request": "launch",
      "name": "Egg Debug",
      "runtimeExecutable": "npm",
      "runtimeArgs": [
        "run",
        "debug"
      ],
      "console": "integratedTerminal",
      "restart": true,
      "protocol": "auto",
      "port": 9999
    },
    {
      "type": "node",
      "request": "launch",
      "name": "Egg Debug with brk",
      "runtimeExecutable": "npm",
      "runtimeArgs": [
        "run",
        "debug",
        "--",
        "--inspect-brk"
      ],
      "protocol": "inspector",
      "port": 9229
    },
    {
      "type": "node",
      "request": "launch",
      "name": "Egg Test",
      "runtimeExecutable": "npm",
      "runtimeArgs": [
        "run",
        "test-local",
        "--",
        "--inspect-brk"
      ],
      "protocol": "auto",
      "port": 9229
    },
    {
      "type": "node",
      "request": "attach",
      "name": "Egg Attach to remote",
      "localRoot": "${workspaceRoot}",
      "remoteRoot": "/usr/src/app",
      "address": "localhost",
      "protocol": "auto",
      "port": 9999
    }
  ]
}
@shepherdwind

This comment has been minimized.

Copy link

shepherdwind commented Apr 20, 2018

赞,我这边好像需要 npm run debug,然后手动点击一下 Egg Attach to remote 才行

@yaojijiayou

This comment has been minimized.

Copy link

yaojijiayou commented Apr 23, 2018

会出现
image

//----下面这个问题我也遇到了。。-------------------------
手动执行egg-bin debug,然后使用Egg Attach to remote,虽然正常attach上去了,但是无法打断点。。。

@xingyesh

This comment has been minimized.

Copy link

xingyesh commented Apr 27, 2018

npm run debug,然后使用vscode Egg Attach to remote 可以。但是真的很容易断开啊,随便改的东西就需要重新执行

@atian25

This comment has been minimized.

Copy link
Owner Author

atian25 commented Apr 27, 2018

你连接 9999 端口就不会断了

@atian25

This comment has been minimized.

Copy link
Owner Author

atian25 commented May 16, 2018

等会 egg-cluster 这个 PR 合并发布后,就可以解决了。

vscode 最新版对 --debug-port 不再支持了,8.x 后换为 --inspect-port

PS: 最近较忙,其实这种问题,遇到的同学,提炼一个最小可复现案例,跟 vscode 一反馈,早就能解决了。 Microsoft/vscode#49865 就这么简单。

@wxfred

This comment was marked as off-topic.

Copy link

wxfred commented May 16, 2018

--debug-port没找到在哪,我看了一下你提交给微软的那个链接,发现--debug-port是写在代码里的是吧?我也不确定,也不知道在哪改,然后只能用npm更新到最新的eggjs,启动调试后没有那个错误弹窗了,但是无法成功启动。我的sequelize初始化成功了,没更新egg前会在sequelize这些初始化前弹窗然后卡死。

PS G:\Nodejs Development\Project> cd 'g:\Nodejs Development\Project'; & 'C:\Program Files\nodejs\npm.cmd' 'run' 'debug' '--' '--inspect-brk'

Project@1.0.0 debug G:\Nodejs Development\Project
egg-bin debug "--inspect-brk"

Debugger listening on ws://127.0.0.1:9229/97b90d18-5e76-4a7c-a9de-25d3d047b4d5
For help see https://nodejs.org/en/docs/inspector
Debugger attached.
2018-05-16 14:16:51,847 INFO 22160 [master] node version v8.11.1
2018-05-16 14:16:51,850 INFO 22160 [master] egg version 2.8.1
Debugger listening on ws://127.0.0.1:5800/337d2144-61ce-4263-82d4-71cd9ae3ddfb
For help see https://nodejs.org/en/docs/inspector
Debugger attached.
sequelize deprecated String based operators are now deprecated. Please use Symbol based operators for better security, read more at http://docs.sequelizejs.com/manual/tutorial/querying.html#operators node_modules\sequelize\lib\sequelize.js:242:13
2018-05-16 14:16:55,586 INFO 10620 [model] SELECT 1+1 AS result (7ms)
2018-05-16 14:16:55,589 INFO 22160 [master] agent_worker#1:10620 started (3730ms)
Debugger listening on ws://127.0.0.1:9230/ea613009-c647-4a6f-98cf-d14d76c6746d
For help see https://nodejs.org/en/docs/inspector
9230 opened
Debug Proxy online, now you could attach to 9999 without worry about reload.
DevTools → chrome-devtools://devtools/bundled/inspector.html?experiments=true&v8only=tru
e&ws=127.0.0.1:9999/ws_proxy
Debugger attached.
sequelize deprecated String based operators are now deprecated. Please use Symbol based operators for better security, read more at http://docs.sequelizejs.com/manual/tutorial/querying.html#operators node_modules\sequelize\lib\sequelize.js:242:13
2018-05-16 14:16:58,876 INFO 12060 [model] SELECT 1+1 AS result (0ms)
2018-05-16 14:16:59,856 ERROR 12060 nodejs.ECONNREFUSEDError: connect ECONNREFUSED 127.0.0.1:6379
at Object._errnoException (util.js:1022:11)
at _exceptionWithHostPort (util.js:1044:20)
at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1198:14)
code: 'ECONNREFUSED'
errno: 'ECONNREFUSED'
syscall: 'connect'
address: '127.0.0.1'
port: 6379
name: 'ECONNREFUSEDError'
pid: 12060
hostname: DESKTOP-6GQG52D
// 然后一直重复 ECONNREFUSEDError

@atian25

This comment has been minimized.

Copy link
Owner Author

atian25 commented May 16, 2018

ECONNREFUSEDError 明显是你的数据库配置地址不对。

egg-cluster 已经发布了,升级安装下依赖即可

hey, please retry after reinstall dependencies and please never lock it.

$ # reinstall deps and never lock it.
$ rm -rf node_modules yarn.lock package-lock.json
$ npm i --no-package-lock
@wxfred

This comment has been minimized.

Copy link

wxfred commented May 16, 2018

@atian25 非常感谢你及时的回复。sequelize没问题,原因是没开启redis服务o(╥﹏╥)o

@shiyun

This comment has been minimized.

Copy link

shiyun commented Jun 8, 2018

请问,node_modules里的模块为什么有时候可以打断点,有时候不行?

@atian25

This comment has been minimized.

Copy link
Owner Author

atian25 commented Jun 9, 2018

@shiyun 是不是跟加载时机有关?如果你用最新的方式的话,应该是有 --inspect-brk 的,这样的话应该是可以断点到的。

@shiyun

This comment has been minimized.

Copy link

shiyun commented Jun 11, 2018

@atian25 是用的最新的方式,用--inspect断点不到,后面改成--inspect-brk也样断点不到,问了好几个朋友都遇到这样的问题,没找到解决办法。
提示信息是: "未验证的断点,已设置断点但还未绑定"

@atian25

This comment has been minimized.

Copy link
Owner Author

atian25 commented Jun 14, 2018

@shiyun 你是用 cnpm 的么?刚跟 vscode 那边的人交流了,好像是软链方式会导致他们找不到,已经提 issue 待修复,着急的话先换回 npm

Updated: 如果要 debug 启动期的代码,换回 npm 方式即可。

Microsoft/vscode#51588

@yuu2lee4

This comment has been minimized.

Copy link

yuu2lee4 commented Aug 1, 2018

调试配置里面 没有egg ,在js里输入egg,再去调试配置里就有了,但是生成的config为空,npm run debug后没有自动attach,环境:
vscode: 1.25.1
os: macos10.13.6
yarn: 1.5.1
node: 10.7.0
typescript: 3.0.1

@atian25

This comment has been minimized.

Copy link
Owner Author

atian25 commented Aug 1, 2018

@yuu2lee4 直接复制文档中那段即可

@galleonsZcc

This comment has been minimized.

Copy link

galleonsZcc commented Aug 1, 2018

刚安装的,debug配置项里没有egg,js里输入egg也没有任何的关联。。然后把vs安装了最新版,还是没有用,需要配置什么吗?

~
试了下,js里还是没有开启联想,但是选择node的debug环境并手动复制config进去,还是可以跑。
那这个插件好像跟没装一样了。。

@dryqiao

This comment has been minimized.

Copy link

dryqiao commented Aug 2, 2018

vscode同时起两个egg调试服务的时候,9229端口会冲突啊,我改了端口,没有用?

@atian25

This comment has been minimized.

Copy link
Owner Author

atian25 commented Aug 2, 2018

@galleonsZcc 你先直接拷贝文档里面的就好了,vscode 那边升级了,旧的方式不行了,我晚点修复下。

@dryqiao 你要改两个的,一个是 npm run debug -- --inspect-brk=端口号,然后再改那个 port 的。(一个是告诉 node 在指定端口调试,一个是告诉 vscode 去连接这个端口)

@IEfucker

This comment has been minimized.

Copy link

IEfucker commented Aug 3, 2018

谢谢@StephenSeraph ,你的代码Egg Debug配置有效,Egg Debug with brk配置和当前版本的vscode-eggjs配置一样,用不了。是vscode的bug?

请教请教大神@atian25 些问题,
1.vscode-eggjs生成的配置runtimeArgs里,"--" 是什么,空的参数吗
2.另外看到brk的解释是:Break before user code starts,这种说的是什么使用场景
3.attach和launch的使用场景也不理解,何种情况使用哪种
4.我看启动后的log很多,但看不懂是什么意思,是不是启动成功了,或者是否按照想要的方式启动的也不能判断,能帮忙解释下log吗(前两天用vscode-eggjs的默认配置启动debug总是失败,但没有失败提示)

@atian25

This comment has been minimized.

Copy link
Owner Author

atian25 commented Aug 3, 2018

@IEfucker

vscode-eggjs生成的配置runtimeArgs里,"--" 是什么,空的参数吗

看我这篇回答: https://www.zhihu.com/question/267095526/answer/318608937

attach和launch的使用场景也不理解,何种情况使用哪种

debug 其实是 2 个操作:

  • 给程序传参,告诉它开启一个端口,等到被调试
  • 调试器(devtools,vscode)去 attach 这个端口,从而通过 protocol 告诉程序,要在哪些地方断点。

另外看到brk的解释是:Break before user code starts,这种说的是什么使用场景

指的是在 Node 的第一行就断点,而不是等开发者 attach,也就是上面那个问题合成一步,从而可以断点到两步之间的一些逻辑。

@shmilyoo

This comment has been minimized.

Copy link

shmilyoo commented Oct 25, 2018

vscode同时起两个egg调试服务的时候,9229端口会冲突啊,我改了端口,没有用?

@galleonsZcc 你先直接拷贝文档里面的就好了,vscode 那边升级了,旧的方式不行了,我晚点修复下。

@dryqiao 你要改两个的,一个是 npm run debug -- --inspect-brk=端口号,然后再改那个 port 的。(一个是告诉 node 在指定端口调试,一个是告诉 vscode 去连接这个端口)

同时修改两个端口后,又会报Starting inspector on 127.0.0.1:5800 failed: address already in use

@atian25

This comment has been minimized.

Copy link
Owner Author

atian25 commented Oct 26, 2018

@bell8910

This comment has been minimized.

Copy link

bell8910 commented Oct 28, 2018

@atian25 感谢提供配置,可以在vscode调试eggjs了,vscode用的最新版1.28.2

package.json 增加

"scripts": {
    "debug": "egg-bin debug"
  }

launch.json在configurations里增加

{
      "name": "Launch Egg",
      "type": "node",
      "request": "launch",
      "cwd": "${workspaceRoot}",
      "runtimeExecutable": "npm",
      "windows": { "runtimeExecutable": "npm.cmd" },
      // 启动我们的 egg-bin debug 并默认是 brk
      "runtimeArgs": [ "run", "debug", "--", "--inspect-brk" ],
      // 日志输出到 Terminal,否则启动期的日志看不到
      "console": "integratedTerminal",
      "protocol": "auto",
      // 进程重启后自动 attach
      "restart": true,
      // 因为无需再 proxy,故改回原来的 9229 端口
      "port": 9229,
      // 自动 attach 子进程 
      "autoAttachChildProcesses": true
}
@calpa

This comment has been minimized.

Copy link

calpa commented Oct 30, 2018

感谢提供调试配置。

我试了一下利用 ts + egg.js 的组合,然后只需要简单npm run debug 命令就行。再简单一点就是按 npm-scripts里面的 debug,达到一键开始 debug 之旅。

@jyfcrw

This comment has been minimized.

Copy link

jyfcrw commented Nov 1, 2018

请问在WSL里执行 npm run debug,再通过 chrome devtools 调试有试过吗?我遇到的问题是无法命中egg项目里自己写的代码的断点。chrome 70, egg 2.10.0, node 10.5.0

@atian25

This comment has been minimized.

Copy link
Owner Author

atian25 commented Nov 1, 2018

按我的判断跟 egg 本身关系不大。这种只能自己排查,跟环境有关。但只要你对 devtools 断点有理解,一般查起来很快。

  1. 试着删除目录,再重新安装依赖,不要锁版本。

hey, please retry after reinstall dependencies and please never lock it.

$ # reinstall deps and never lock it.
$ rm -rf node_modules yarn.lock package-lock.json
$ npm i --no-package-lock
  1. 然后看下 debug 的日志输出,看看 debug 端口都是哪几个

  2. 然后你的 chrome devtool 去 attach 这几个看看。(或者用 vscode 的 attach 功能试试)

@xiabaiyang

This comment has been minimized.

Copy link

xiabaiyang commented Feb 12, 2019

@shiyun node_modules 里的模块 debugger 的问题你解决了吗?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment