Skip to content
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 · 61 comments
Open

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

atian25 opened this issue Feb 8, 2018 · 61 comments

Comments

@atian25
Copy link
Owner

@atian25 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,
      "disableOptimisticBPs": false,
    }
  ]
}

完美版.最终版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
Copy link
Owner Author

@atian25 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
Copy link
Owner Author

@atian25 atian25 commented Feb 11, 2018

先删除原有的 .vscode 文件

kapture 2018-02-09 at 11 27 33

@zxmajunhong
Copy link

@zxmajunhong zxmajunhong commented Mar 15, 2018

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

@atian25
Copy link
Owner Author

@atian25 atian25 commented Mar 15, 2018

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

@my9074
Copy link

@my9074 my9074 commented Mar 28, 2018

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

@atian25
Copy link
Owner Author

@atian25 atian25 commented Mar 28, 2018

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

image

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

@my9074
Copy link

@my9074 my9074 commented Mar 28, 2018

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

@atian25
Copy link
Owner Author

@atian25 atian25 commented Mar 28, 2018

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

@shepherdwind
Copy link

@shepherdwind shepherdwind commented Apr 4, 2018

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

@atian25
Copy link
Owner Author

@atian25 atian25 commented Apr 4, 2018

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

@atian25
Copy link
Owner Author

@atian25 atian25 commented Apr 4, 2018

或者 npx egg-bin test --grep=

@atian25
Copy link
Owner Author

@atian25 atian25 commented Apr 6, 2018

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

@caohongtao

This comment has been hidden.

@atian25

This comment has been hidden.

@wangtao0101

This comment has been hidden.

@wangtao0101

This comment has been hidden.

@shyser
Copy link

@shyser shyser 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
Copy link

@shepherdwind shepherdwind commented Apr 20, 2018

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

@yaojijiayou
Copy link

@yaojijiayou yaojijiayou commented Apr 23, 2018

会出现
image

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

@xingyesh
Copy link

@xingyesh xingyesh commented Apr 27, 2018

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

@atian25
Copy link
Owner Author

@atian25 atian25 commented Apr 27, 2018

你连接 9999 端口就不会断了

@atian25
Copy link
Owner Author

@atian25 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.

@bell8910
Copy link

@bell8910 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
Copy link

@calpa calpa commented Oct 30, 2018

感谢提供调试配置。

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

@jyfcrw
Copy link

@jyfcrw jyfcrw commented Nov 1, 2018

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

@atian25
Copy link
Owner Author

@atian25 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
Copy link

@xiabaiyang xiabaiyang commented Feb 12, 2019

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

@mistypig
Copy link

@mistypig mistypig commented Mar 8, 2019

今天vscode推送了1.32.1版本,升级以后Debug会卡住。去掉--inspect-brk可以启动成功,但无法打断点,报Breakpoint set but not yet bound。

——————————————
手动打开auto attach解决了。

@atian25

This comment has been hidden.

@atian25
Copy link
Owner Author

@atian25 atian25 commented Mar 12, 2019

@shen-lan
Copy link

@shen-lan shen-lan commented Mar 16, 2019

如何忽略进入node_module文件夹?

@atian25
Copy link
Owner Author

@atian25 atian25 commented Mar 16, 2019

请大家务必务必注意,现在的调试,就是 Node 自己的多进程调试,egg 并没有做什么处理。所以,大部分的问题,需要你们了解 VSCode 和 Node 本身在调试这块的知识。

@atian25
Copy link
Owner Author

@atian25 atian25 commented Apr 2, 2019

更新下最新的一些信息:

  1. 单元测试那个,需要加一个 "disableOptimisticBPs": false, 才能正确的在 test 文件中断点。microsoft/vscode#37199
  2. WebStorm 2019 后, DEBUG_NODE_OPTIONS 这个变量丢失了,不过还是目前看来是不影响断点。
@atian25
Copy link
Owner Author

@atian25 atian25 commented Apr 2, 2019

@whwnow
Copy link

@whwnow whwnow commented May 18, 2019

请问在 win10 下,vscode 版本为1.34.0,在打开 autoAttach设置,使用 wsl 作为默认terminal的情况下,npm run debug --inspect-brk 可以在chrome里正常调试,好像没有 attach, 不能在vscode里调试,这个问题如何解决?

@atian25
Copy link
Owner Author

@atian25 atian25 commented May 20, 2019

@whwnow 如果 autoAttach 开了但没有 attach,那就要找 VSCode 官方提 issue 了。

@Zuckonit
Copy link

@Zuckonit Zuckonit commented Jun 6, 2019

为何每次vscode debug egg项目,第一次打开都会停留在egg源码某个文件的'use strict'这一行

@atian25
Copy link
Owner Author

@atian25 atian25 commented Jun 6, 2019

@Zuckonit 去掉 --inspect-brk,并阅读下正文最后一段,理解下 Node 的调试原理。

@Zuckonit
Copy link

@Zuckonit Zuckonit commented Jun 12, 2019

用了vscode的egg插件,配置默认带了--inspect-brk,或许这个不应该加到默认配置

@whwnow
Copy link

@whwnow whwnow commented Jun 17, 2019

@atian25 我找到解决方案了,在wsl中需要额外安装插件才可以 auto attach 。参考官方这个文档:https://code.visualstudio.com/docs/remote/wsl

@atian25
Copy link
Owner Author

@atian25 atian25 commented Jun 17, 2019

@atian25 我找到解决方案了,在wsl中需要额外安装插件才可以 auto attach 。参考官方这个文档:https://code.visualstudio.com/docs/remote/wsl

喔,你说最新的那个 Remote Development 吧

@whwnow
Copy link

@whwnow whwnow commented Jun 17, 2019

对,是那个

@quanru
Copy link

@quanru quanru commented Jan 2, 2020

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
Copy link
Owner Author

@atian25 atian25 commented Jan 2, 2020

有个环境变量,可以翻下 egg-cluster 的 master.js 源码搜下

@mstar-kk
Copy link

@mstar-kk mstar-kk commented Feb 28, 2020

vscode调试断点灰色的解决:
### 检查auto attach是否开启,最新版本vscode,1.42.1版本,开启auto attach后右下角显示
image
并且命令窗口下有
image

我这边最新版这个功能默认是个disable的状态,需要在设置中开启

image

开启后可以直接命令egg-bin debug开启调试,我觉得每次输入命令麻烦就还是用F5,launch.json配置如下,并且可以直接重启调试:

{
    "version": "0.2.0",
    "configurations": [
        {
            "type": "node",
            "request": "launch",
            "name": "启动程序",
            "runtimeExecutable": "npm",
            "runtimeArgs": [
              "run", "debug"
            ],
            "console": "integratedTerminal",
            "protocol": "auto",
            "port": 9229,
            "restart": true
        }
    ]
}

我可以用,大家可以试试可用否。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet