JavaScript 程序越来越复杂,调试工具的重要性日益凸显。客户端脚本有浏览器,Node 脚本怎么调试呢?
2016年,Node 决定将 Chrome 浏览器的"开发者工具"作为官方的调试工具,使得 Node 脚本也可以使用图形界面调试,这大大方便了开发者。
本文介绍如何使用 Node 脚本的调试工具。
一、示例程序
为了方便讲解,下面是一个示例脚本。首先,新建一个工作目录,并进入该目录。
$ mkdir debug-demo $ cd debug-demo
然后,生成package.json
文件,并安装 Koa 框架和 koa-route 模块。
$ npm init -y $ npm install --save koa koa-route
接着,新建一个脚本app.js
,并写入下面的内容。
// app.js const Koa = require('koa'); const router = require('koa-route'); const app = new Koa(); const main = ctx => { ctx.response.body = 'Hello World'; }; const welcome = (ctx, name) => { ctx.response.body = 'Hello ' + name; }; app.use(router.get('/', main)); app.use(router.get('/:name', welcome)); app.listen(3000); console.log('listening on port 3000');
上面代码是一个简单的 Web 应用,指定了两个路由,访问后会显示一行欢迎信息。如果想了解代码的详细含义,可以参考 Koa 教程。
二、启动开发者工具
现在,运行上面的脚本。
$ node --inspect app.js
上面代码中,--inspect
参数是启动调试模式必需的。这时,打开浏览器访问http://127.0.0.1:3000
,就可以看到 Hello World 了。
接下来,就要开始调试了。一共有两种打开调试工具的方法,第一种是在 Chrome 浏览器的地址栏,键入 chrome://inspect
或者about:inspect
,回车后就可以看到下面的界面。
在 Target 部分,点击 inspect 链接,就能进入调试工具了。
第二种进入调试工具的方法,是在 http://127.0.0.1:3000 的窗口打开"开发者工具",顶部左上角有一个 Node 的绿色标志,点击就可以进入。
三、调试工具窗口
调试工具其实就是"开发者工具"的定制版,省去了那些对服务器脚本没用的部分。
它主要有四个面板。
- Console:控制台
- Memory:内存
- Profiler:性能
- Sources:源码
这些面板的用法,基本上跟浏览器环境差不多,这里只介绍 Sources (源码)面板。
四、设置断点
进入 Sources 面板,找到正在运行的脚本app.js
。
在第11行(也就是下面这一行)的行号上点一下,就设置了一个断点。
ctx.response.body = 'Hello ' + name;
这时,浏览器访问 http://127.0.0.1:3000/alice ,页面会显示正在等待服务器返回。切换到调试工具,可以看到 Node 主线程处于暂停(paused)阶段。
进入 Console 面板,输入 name,会返回 alice。这表明我们正处在断点处的上下文(context)。
再切回 Sources 面板,右侧可以看到 Watch、Call Stack、Scope、Breakpoints 等折叠项。打开 Scope 折叠项,可以看到 Local 作用域和 Global 作用域里面的所有变量。
Local 作用域里面,变量name
的值是alice
,双击进入编辑状态,把它改成bob
。
然后,点击顶部工具栏的继续运行按钮。
页面上就可以看到 Hello bob 了。
命令行下,按下 ctrl + c,终止运行app.js
。
五、调试非服务脚本
Web 服务脚本会一直在后台运行,但是大部分脚本只是处理某个任务,运行完就会终止。这时,你可能根本没有时间打开调试工具。等你打开了,脚本早就结束运行了。这时怎么调试呢?
$ node --inspect=9229 -e "setTimeout(function() { console.log('yes'); }, 30000)"
上面代码中,--inspect=9229
指定调试端口为 9229,这是调试工具默认的通信端口。-e
参数指定一个字符串,作为代码运行。
访问chrome://inspect
,就可以进入调试工具,调试这段代码了。
代码放在setTimeout
里面,总是不太方便。那些运行时间较短的脚本,可能根本来不及打开调试工具。这时就要使用下面的方法。
$ node --inspect-brk=9229 app.js
上面代码中,--inspect-brk
指定在第一行就设置断点。也就是说,一开始运行,就是暂停的状态。
六、忘了写 --inspect 怎么办?
打开调试工具的前提是,启动 Node 脚本时就加上--inspect
参数。如果忘了这个参数,还能不能调试呢?
回答是可以的。首先,正常启动脚本。
$ node app.js
然后,在另一个命令行窗口,查找上面脚本的进程号。
$ ps ax | grep app.js 30464 pts/11 Sl+ 0:00 node app.js 30541 pts/12 S+ 0:00 grep app.js
上面命令中,app.js
的进程号是30464
。
接着,运行下面的命令。
$ node -e 'process._debugProcess(30464)'
上面命令会建立进程 30464 与调试工具的连接,然后就可以打开调试工具了。
还有一种方法,就是向脚本进程发送 SIGUSR1 信号,也可以建立调试连接。
$ kill -SIGUSR1 30464
七、参考链接
- Debugging Node.js with Google Chrome, by Jacopo Daeli
- Debugging Node.js with Chrome DevTools, by Paul Irish
- Last minute node debugging, by Remy Sharp
(完)
FaiChou 说:
很不错的node调试入门教程
2018年3月20日 08:52 | # | 引用
魅鬼 说:
赞啊,才知道原来浏览器还能调试nodejs,牛逼的chrome,多谢阮老师!
2018年3月20日 09:21 | # | 引用
James 说:
直接用VS CODE的调试功能就行了吧,简单方便。
2018年3月20日 09:26 | # | 引用
Simon 说:
学到了,多谢阮老师!j
2018年3月20日 09:45 | # | 引用
disguiser 说:
vscode + postman 很方便易用
2018年3月20日 10:01 | # | 引用
hooyes 说:
就是说加上 --inspect 参数,Node 服务器就把源代码推向了浏览器了?
2018年3月20日 10:02 | # | 引用
riskers 说:
可以添加一个 VSCode 调试的说明
2018年3月20日 10:20 | # | 引用
Passenger 说:
VSCode + 1
2018年3月20日 10:36 | # | 引用
hoosin 说:
阮老师,你怕不知道什么是端口
2018年3月20日 11:22 | # | 引用
安娜 说:
这,阮老师的东西,好多都是翻译呀
2018年3月20日 11:29 | # | 引用
lveyo 说:
The legacy debugger has been deprecated as of Node 7.7.0. Please use --inspect and Inspector instead. 看来得7.7以后才能用这个inspect
2018年3月21日 11:05 | # | 引用
阿良良 说:
推荐用vscode调试node.js代码
2018年3月21日 14:53 | # | 引用
一别经年 说:
在开发node的命令行程序时候,怎么去做调试?
2018年3月21日 22:49 | # | 引用
cnqn 说:
弄了半天,终于搞成功了。感谢
2018年3月23日 15:44 | # | 引用
一只前端狗 说:
用的什么富文本编辑器啊?很美观
2018年3月23日 17:06 | # | 引用
厌敷衍 说:
打开调试工具“Developer Tools - Node.js”添加完连接后,对应的地址会持续不断的收到一个GET请求到路由 "/json/version"
我本地需要对应添加什么配置文件么?
具体https://nodejs.org/en/docs/inspector/ 也没找到说明,为什么会有这个请求哦?
2018年3月26日 09:56 | # | 引用
xiatian 说:
远程调试还是不太方便
2018年3月26日 10:07 | # | 引用
雨寒 说:
老师有时间能不能写一篇 Vue 的小教程?
2018年3月26日 15:49 | # | 引用
弥左拉 说:
很早就想学javascript,觉得这们语言富有艺术性,可是到现在,生活种种的诱惑浪费了我大把的时间,今年我25,好像越来越大了,再想继续学起。你说怎样
2018年3月27日 11:43 | # | 引用
小媒体 说:
看了这么多关于Node调试的,只有这篇收获最大。
2018年3月29日 18:39 | # | 引用
唐竟成 说:
没有必要在chrome中打断点,可以在js脚本里写个 “debugger”,这样方便点啊。
2018年4月 3日 09:08 | # | 引用
安全上网 说:
可能是我思维懒吧。总感觉 Node 的东西都特别复杂。
2018年4月 3日 16:30 | # | 引用
ksat 说:
VSCode + 1
2018年4月13日 09:30 | # | 引用
似水 说:
vscode的调试怎么用,没用过。不知道咋玩
2018年5月16日 12:08 | # | 引用
ycw 说:
使用Chorme这种调试方法是不是只能调试 Get请求?其他请求可以吗?
2018年8月30日 10:18 | # | 引用
ycw 说:
请问如果是其他类型的请求(post、delete)怎么调试?
2018年8月30日 14:35 | # | 引用
杰哥 说:
刚刚学到node搭建服务器,很实用啊
2018年9月 3日 18:10 | # | 引用
R 说:
ndb 也可以用啦
2018年11月28日 22:38 | # | 引用
义 说:
因为本地开发方便的问题,启动服务采用了pm2模块,但是又想用到node模块的inspect调试功能,有没有方法,查了一下资料,好像没看到pm2调试的方法。
2019年2月18日 16:54 | # | 引用
敲代码的李二狗 说:
非常感谢 这种 实用的介绍!!! 另外 vscode 中 好像不能实现 ts文件 的 调试功能,如果 可以实现,请知情人士告知一下~非常感谢
2019年2月22日 15:50 | # | 引用
學生 说:
感謝阮老師,減少摸索時間
能有更多時間對開源社區做貢獻
2019年8月22日 18:22 | # | 引用
祖安宁哥 说:
支持阮老师,有些杠精真是服了,这篇文章只是提供了一种调试的新方式,杠精非要说用vscode就行了,你当别人不知道vscode?
2020年5月27日 09:31 | # | 引用
fjqingyou 说:
在使用 node -e 'process._debugProcess(30464)' 进入了调试模式。在不需要再调试时,有没有办法退出调试状态?即达到关闭调试的端口、不再接受调试请求?
2022年3月28日 16:01 | # | 引用
joe 说:
找来找去,花个几个小时google,最后还是发现大佬您给了答案,跪谢!
2022年9月20日 13:31 | # | 引用