Nodejs 调试代码一

很长一段时间,调试 Nodejs 代码都是通过在代码里写 console.log() 进行的。在 infoq 上看到一篇文章,是说十倍效率工程师有哪些特质,其中一点就是擅长调试与测试。这给了我很大动力去弄明白这些之前模糊的概念。

调试服务端

创建 index.js,在服务端想要运行该文件,需要在终端输入 $ node index.js。
node 程序 会读取 index.js 源码,如果 index.js 中引用了其它 js 文件,依次读取源码,最后执行。

(安装的 Nodejs 软件里包含很多个子程序,node 是其中一个程序,用于执行 js 文件)

图1

在调试 Nodejs 代码时,我们希望代码能一行行执行,而不是像 node 程序那样将整个源码都跑完,这时候需要用 Nodejs 内置的 调试器程序 去运行 index.js。

图2

总结下目前了解的概念:

  • 安装的 Nodejs 软件包会包含很多子程序,比如 node 程序和调试器程序;
  • node 程序的特点是一下子将整个代码都跑完;
  • 调试器程序的特点是一行行执行代码;

调试器程序执行 js 文件后,会启一个 websocket 的服务,调试器程序作为服务端,只提供与调试相关的底层功能,这样做的好处是开发人员可以自由选择调试客户端:你可以选择在终端中调试,也可以选择在谷歌浏览器中调试,甚至可以在 Vscode 中调试,只要你的调试客户端连接到调试服务端即可。

图3

创建 index.js 文件作为调试演示代码,内容如下:

const add = require('./add')

const a = 1
const b = 2

debugger
console.log(add(a, b))

下面分别介绍用不同的调试器客户端进行调试。

终端中调试

Nodejs 也自带了一个调试器客户端,在终端中进行调试。

$ node inspect index.js

node inspect 表示启动调试器服务端,并在终端打开调试器客户端。

$  node inspect index.js
< Debugger listening on ws://127.0.0.1:9229/858f5307-2af1-472a-bd73-a2fbe5b8578b
< For help, see: https://nodejs.org/en/docs/inspector
< Debugger attached.
Break on start in index.js:1
> 1 const add = require('./add')
  2
  3 const a = 1
debug>

第一行 Debugger listening on ws://127.0.0.1:9229/,表示调试服务端已经启动了,并且监听着 9229 这个端口。
第三行 Debugger attached,表示调试器客户端已经连接到调试器服务端了。

输入 help 可以查看调试器有哪些用法。

debug> help
run, restart, r       Run the application or reconnect
kill                  Kill a running application or disconnect

cont, c               Resume execution
next, n               Continue to next line in current file
step, s               Step into, potentially entering a function
out, o                Step out, leaving the current function
backtrace, bt         Print the current backtrace
list                  Print the source around the current line where execution
                      is currently paused

setBreakpoint, sb     Set a breakpoint
clearBreakpoint, cb   Clear a breakpoint

......

debug>

输入 n,执行下一行代码。

debug> n
break in index.js:3
  1 const add = require('./add')
  2
> 3 const a = 1
  4 const b = 2
  5

输入 c,跳转到下一个断点处。

debug> c
break in index.js:6
  4 const b = 2
  5
> 6 debugger
  7 console.log(add(a, b))
  8

还有一些常用的命令,在 help 中可以查看详细用法,这里简要列举下,就不一一介绍了。

  • restart 重启调试器
  • run 开始调试
  • kill 停止调试
  • s 单步跳进
  • o 单步跳出

Chrome Devtool 中调试

谷歌浏览器的开发者工具也可以作为调试客户端调试 Nodejs 代码,只要连接到调试器服务端即可。

$ node --inspect-brk index.js
Debugger listening on ws://127.0.0.1:9229/7513b18d-7a62-44c7-a963-84a90eb826a9
For help, see: https://nodejs.org/en/docs/inspector

node --inspect-brk 表示只启动了调试器服务端,监听端口 9229。此时还没有任何调试器客户端连接哦~~

打开谷歌浏览器的开发者工具,左上角可以看到 nodejs 的 logo,点它。

图4

点击之后弹出的新窗口就是Chrome Devtools 中调试 Nodejs 代码的调试客户端。

  • 红字1:窗体标题表示这是 Nodejs 的调试客户端;
  • 红字2(Console):服务端打印的日志(console.log)也会在这里打印;
  • 红字3(Sources):服务端源代码,调试器并不会见所有服务端代码都推送到这里,只会推送用到的代码;
  • 红字4:源码文件,可以点击想要打断点的文件,在右侧打断点调试;
  • 红字5(Scope):变量的具体值在这里可以找到。
图5

此时回到终端,可以看到多打印一条消息,最后一行表示调试器客户端连接到调试器服务端了。

$  node --inspect-brk index.js
Debugger listening on ws://127.0.0.1:9229/0a233e15-573b-40a0-956f-76c8e074b5a1
For help, see: https://nodejs.org/en/docs/inspector
Debugger attached.      <=============

为什么打开谷歌浏览器的 Chrome Devtools,会自动连接调试器服务端呢?

调试器服务端默认启动端口是 9229,而 Chrome Devtools 默认也会连接 9229 端口。
重新启动调试器服务端,并且指定一个不一样的端口,此时调试器服务端端口变成了 9222。

$  node --inspect-brk=9222 index.js 
Debugger listening on ws://127.0.0.1:9222/967b99ee-b726-4c2b-ba08-dec16f1a531a
For help, see: https://nodejs.org/en/docs/inspector

再次打开浏览器,可以看到 Nodejs 的 logo 变成灰色了,也不会主动连接到调试器服务端了。此时需要我们手动设置下 Chrome Devtools 去连接哪个端口。

点击 Nodejs 的 logo 图像,在弹出的窗体中选择 Connection(红字1),点击 Add connection(红字2),在上方的输入框输入要监听的端口号保存即可。

图6

Vscode 中调试

大多数开发者调试代码都会选择 IDE(开发工具) 进行调试,这里以 Vscode 为例进行说明。

用 Vscode 打开 index.js 所在的目录。

图7

这里主要介绍下红字 3 的几个属性的含义:

  • type: "node",表示调试 Nodejs 代码,如果调试 PHP 代码,这里写成 type: php;
  • request: "launch",launch 表示由 调试器程序 执行 index.js,而不是由 node程序 执行 index.js,参考第一点调试器服务端。request 还有一个值 attach,下文再介绍;
  • name: "Launch Program",红字2左边有个下拉框,name 属性的值即为下拉框中的值;
  • program: "${workspaceFolder}/index.js",启动哪个文件,这里表示启动根目录下的 index.js 文件。
图8
  • 红字1(调试控制台):可以看到启动了调试器服务端,监听端口 26199,每次调试端口都不一样。Debugger attached 表示调试客户端也连接上服务端了;
  • 红字2:调试的相关操作都在这里;
  • 红字3:调试过程中变量和表达式的值可以在这里查看。
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,053评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,527评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,779评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,685评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,699评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,609评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,989评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,654评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,890评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,634评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,716评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,394评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,976评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,950评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,191评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,849评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,458评论 2 342

推荐阅读更多精彩内容