新学习一种技术,肯定会遇到很多坑,我们需要找到这些坑,弄清楚这些坑出现的原因和其中的原理。这种操作就叫做调试。
程序调试的方法和工具多种多样,在这里我总结一下我在学习nodejs的过程中,学到的和用到的调试方法。
log
在JavaScript代码中直接console.log,可以在控制台中打印信息。但是这样的功能太单调,项目中模块很多,功能繁杂,如果没有一个约定好的console.log方法,很容易就导致打印的信息十分杂乱,可读性很差。
nodejs有一个debug模块,提供:
定义log模块,选择特定模块log输出
模块文字颜色高亮
log时间记录
输出log到文件等功能
首先
npm init、npm install debug –save 新建一个nodejs项目并安装debug模块
然后新建
app.js
var debug=require("debug")("mydebug:http"),
work=require("./work"),
http=require("http");
http.createServer(function(req,res){
debug(req.method + ' ' + req.url);
res.end('hello\n');
}).listen(3000,function(){
debug("listening");
});
work.js
var debug=require("debug")("mydebug:work");
setInterval(function(){
debug("doing some work @ %s —— %s",new Date().getTime(),"with supervisor");
},2000);
上面两个文件中分别创建了 mydebug:http 和 mydebug:work 两个log模块,在启动项目的时候可以配置要打印的log模块,这个配置是支持通配符匹配的
在linux中启动: DEBUG=mydebug:* node app.js 在windows中启动 set DEBUG=mydebug:* & node app.js
这样就可以看到不同模块的日志打印了,同时也可以看到日志输出时间。
在浏览器中访问 localhost:3000 也可以看到打印出的访问信息
此外debug模块还提供把日志输出到文件的功能
set DEBUG=mydebug:* & node app.js mydebug:work> debug.log
nodejs debug模块文档: https://github.com/visionmedia/debug
debug
光有log还不够,当程序出现问题时通过log可以定位到错误位置,但是当我们想查看错误现场的变量时,log就无能为力了,一般情况下我们不会把所有的变量都打印出来。此时就需要断点的功能了,在程序里边打上断点,直接定位到错误位置,分析错误现场确认错误原因。
nodejs内部提供一个debug机制,可以让程序进入debug模式,供开发者一步一步分析代码发现问题。
共有3中启动参数可以让程序进入debug模式
node debug app.js node --debug app.js node --debug-brk app.js
3种模式在调试形式上有一定区别。
node debug app.js
1.这种方式启动程序,程序会进入debug模式,并运行到启动文件的第1行就停止,等待开发者下发往下走的命令
2.这种方式启动程序,直接在当前cmd中进入调试模式
node –debug app.js
1.这种方式启动程序,程序会进入debug模式,并运行完所有代码。这种启动方式往往用于程序启动的过程中不需要调试,通过触发时间进入回调函数的情况,比如在某个http请求中打上断点,等待客户端访问后进入断点
2.这种方式启动程序,会开启一个TCP的端口监听,在本cmd中不进入调试模式,需要另外开启终端用node debug 命令连接调试端口
命令为 node debug localhost debug端口
或者 node debug p node进程id
node –debug-brk app.js
1.这种方式启动程序,程序会进入debug模式,但是不会运行代码,直到有一个终端连接到了debug端口,才开始执行代码,并在第1行进入断点
2.这种方式启动程序,会开启一个TCP的端口监听,在本cmd中不进入调试模式,需要另外开启终端用node debug 命令连接调试端口
进入debug模式后,可以通过一些命令来设置断点、取消断点以及控制程序执行流程
命令文档:https://nodejs.org/api/debugger.html#debugger_commands_reference
流程控制相关
cont
,c
- Continue executionnext
,n
- Step nextstep
,s
- Step inout
,o
- Step outpause
- Pause running code (like pause button in Developer Tools)
断点设置取消相关
setBreakpoint()
,sb()
- Set breakpoint on current linesetBreakpoint(line)
,sb(line)
- Set breakpoint on specific linesetBreakpoint('fn()')
,sb(...)
- Set breakpoint on a first statement in functions bodysetBreakpoint('script.js', 1)
,sb(...)
- Set breakpoint on first line of script.jsclearBreakpoint('script.js', 1)
,cb(...)
- Clear breakpoint in script.js on line 1
变量查看相关
backtrace
,bt
- Print backtrace of current execution framelist(5)
- List scripts source code with 5 line context (5 lines before and after)watch(expr)
- Add expression to watch listunwatch(expr)
- Remove expression from watch listwatchers
- List all watchers and their values (automatically listed on each breakpoint)repl
- Open debugger’s repl for evaluation in debugging script’s context
repl模式下可以输入变量名查看变量内容
node debug
从第一行代码开始进入断点,命令n进入下一行
node –debug
cmd1 开启调试端口
cmd2 连接调试端口
设置断点,取消断点
cmd1 过了一分钟才继续打印
用进程id的方式连接调试模块
上图可以看到pid为4436
repl模式
调试相关的工具和模块
上面的调试过程还是略显麻烦,有一些工具和node模块可以用来辅助调试。
supervisor
supervisor是一个node模块,用来启动node项目。
supervisor可以监控一些文件,当这些文件发生变化时自动刷新程序,不用重新启动node程序。
当程序崩溃时,supervisor会重新启动程序。
还有其他的一些配置,可以在supervisor文档中看到 https://github.com/petruisfan/node-supervisor/
安装supervisor
npm install -g supervisor
监控work.js的变化并启动node程序
把work中的debug信息修改一下
在任务管理器中结束app.js的node进程,可以看到supervisor自动重启了app.js的进程
webstorm
webstorm提供了比较方便的debug工具
在菜单中 run-debug-app.js
可以直接在行号的地方点击,打上断点
浏览器访问 localhost:3000,进入断点
可以看到webstorm提供的一些调试工具
实际上webstorm的调试功能也是基于 –debug-brk来实现的,使用了63797端口来调试
node-inspector
如果不喜欢webstorm的调试工具,还可以使用我们熟悉的chrome调试工具来调试node代码,不过需要安装一个node模块——node-inspector
npm install -g node-inspector
安装完成后,开启一个node调试端口 12345
然后新开一个cmd,开始一个node-inspector调试服务,连接到刚刚开启的调试端口
根据提示访问地址,即可使用我们比较熟悉的chrome的调试工具来调试nodejs代码
- 本文固定链接: http://madong.net.cn/index.php/2016/04/552/
- 转载请注明: 管理员 于 小东 发表