elipse打造Nodejs的调试环境
自从NODEJS问世以来,我们注意到的一个现象是,开源生态围绕Nodejs的扩展(Extends)、插件(Plugins)或工具 (Tools/Utilis)在不断地增多,可见当中之蓬勃。这一方面固然很好,但这里却不是重点讨论那些扩展或者插件,而是调试工具(debugger)本身。因为,没有一个调试工具,无法展开一丁点的开发工作,或者困难重重。大家心知肚明,调试器自必然不可或缺。官方 nodejs.org对调试器的态度也是不含糊的。原来,官方一早在nodejs内置基于Eclipse debugger plugin for V8 调试器的接口,为调试提供安排一套解决方案;另外还有一文编写针对“调试”的教程——本文恰恰是得益于出自于出自ry之手的这份教程 提炼而来。
话说Eclipse是一个大平台,开源的,任何有构思的东东都可以自由地在Eclipse平台上施展,好不快活,呵呵!急不及待地先看看这个调试器的界面,大概是这样的,
图一
图乃经典的Eclipse的风格的界面~但Eclipse,与nodejs的调试,本不互为一体,从何说起呢?Nodejs即就是Google V8的高层扩展,调试过程中还是必须经过V8下面打交道。Google V8引擎只是一个地道的JavaScript解释引擎,不包含调试模块在内,也就是说需要借助另外的调试模组参与之。所以V8/nodejs暴露开放了相关的调试接口,通过这些接口,整合到专门的调试模块中去,像Eclipse Debug View,如此就可以呈现一个专业的调试环境。
本文所介绍的调试器是Google Chrome Developer Tools,定位在面向Chrome开发者的工具包,而此刻我们就是借助它这个工具来调试nodejs的。Google Chrome Developer Tools在原理上是基于TCP远程的调试环境的这么一个Eclipse插件。作者ry有考虑到,直接在C++/Java的最终环境中加入调试器而不远程调试的,——为什么不这样做?原因是什么?作者的说法是为了避免插件在C++/Java运行时带来的不稳定性。
好,休费多唇舌,咱们从基础部分进入调试nodejs的介绍。首先是安装Google Chrome Developer Tools。假设用户已经了解Eclipse的基本使用(熟悉怎么安装的用户则可以跳过此步……),进入菜单选择【Help】--【Software Updates...】,如下图。
出现对话框后切换至【Available Software】标签页,如下图。
然后点击右方的【Add Site……】按钮,有否出现一个输入url网址的对话框?这是Google Chrome Developer Tools的下载地址了,我们贴上:
http://chromedevtools.googlecode.com/svn/update/dev/
然后确认OK,稍等待片刻,如果出现http://chromedevtools.googlecode.com/svn/update/dev/的树菜单,在其前面打勾选择下载。接着点击右边的【install……】。
稍等片刻计算依赖关系……
在【Review Licenses】的窗体中确认许可,然后点击【Next】,正式开始安装:
安装进度100%之后重启Eclipse IDE使插件生效。然后在菜单【Windows】--【Show View】--选择【Debug】切换到Eclipse的调试视图,即图一的界面(还没链接Nodejs),如下图。到这一步,调试插件被安装完成,接着是设置调试器的部分。
如上图红色区域,点击【Debug】的图标旁边的倒三角,出现下拉菜单点击【Debug Configurations …】。然后从左边的选择项之中点击【Standalone V8 VM(独立V8虚拟机)】接着右键鼠标,选择【New】新建一个调试profile。
如下图,输入名称【name】和端口【Port】。可以设置端口为Node-5858、Node-5859、Node-5860……等等,但必须与nodejs脚本中所指定的端口一致。
最后点击【Debug】按钮旋即计入调试界面(如图一)。至此,我们安装调试插件和设置端口部分已经完成了。打算了解如何在js代码中进一步的调试吗?例如打点、步进、监视等的调试基本操作内容……在下一篇中将为大家作介绍!
现在正式进入要调试程序肯定要有调试代码。下面就是我们第一个测试的代码,很小的行数:
- var sys = require('sys');
- // 此乃计数器变量,Suspend(中断挂起)期间可以观察该变量的变化。
- var count = 0;
- sys.debug("开始进行调试……");
- function timer_tick() {
- count++;
- sys.debug("计数器:" + count);
- if (count === 10) {
- count += 1000;
- sys.debug("能在这里打点吗?错过10后不行啦");
- }
- setTimeout(timer_tick, 1000);
- }
- timer_tick();
该段代码是最简单清晰不过的了,就是通过一个count的累加器不断地让nodejs运行作累加。怎么运行这段代码?呵呵,如果尚未清楚如何执行一个最简单的nodejs的话还是在这里交待一下:在CMD命令行键入(须当前nodejs目录下)nodejs dbgtest.js。nodejs.exe的参数是javascript的源码文件。但是因为现在我们是调试的情景,必须加上“--debug”的参数打开调试的接口,即node –debug <文件名>。另外,nodejs还支持--debug-brk的参数,下文再讲。
输入命令nodejs -- debug dbgtest.js后运行的截图如下:
如图则是成功运行nodejs的情况,正常情况下不断累加计数器(count++)。本身是console输出的地方,通过观察console的提示,我们可以看到nodejs内部已经在内容打开5858的端口等待远程调试器,此刻我们接着要做的就是运行Eclipse(进入Debug View),两者一起配合调试的工作,——这就是“远程”而非本地调试的含义。怎么看是否在Debug的视图(View)下呢?留意一下 是否被选中即可,在Eclipse的右上角。
进入下一步的讲述之前有必要加入一个小插曲,就是提及一下nodejs所支持的调试命令(Thanks to Nodejs sys对象),列举如下:
- sys.debug() 同步打印,调试的时候很有用
- sys.log()带时间的输出信息
- sys.error()输出信息
- sys.inspect(object, showHidden, depth) 显示一个对象的所有描述,如果showHidden为false时,只显示名称,没有省略。Depth指定隔多长时间去递归对象,默认是两次
- sys.puts() 类似与document.writeln(),在屏幕上打印,在末尾添加换行
- sys.print() 类似与document.write(),在屏幕上打印,没有换行
用户测试一下各个方法,很容易了解其用途。例如sys.puts(sys.inspect(sys,false,null)); ,结果如下:
- //输出结果
- {
- print:[Function],
- puts:[Function],
- debug:[Function],
- error:[Function],
- inspect:[Function],
- p:[Function],
- log:[Function],
- exec:[Function],
- inherits:[Function]
- }
再回到Eclipse调试视图中。如下图表明链接nodejs成功,可以进行相关的调试工作。
切换至Project Explorer标签页,这里列出了所有的require()包文件和nodejs.exe <文件名>所指定的主程序文件,都是JavaScript(*.js)文件。
我们双击打开程序文件dbgtest.js,即可打开源码:
在行数上方双击那一行,就是一个打点的工作(breakpoint),程序随即被挂起,暂停工作,调试器中显示当地变量等的信息供用户观察与进一步应用。如图我们在第8行打了一个点:
首次使用Eclipse的调试界面感觉可能有些别扭,这没有关系。如果不太习惯,使用多几次就好。调试的基本内容大抵是那几回事。例如,你可以步进跟踪代码(step into,快捷键F5,但注意一点,对于步进require可能会crash挂掉,这也是情有可原的,require()是加载包的特殊方法)。下图则是调出watch的功能。
当然,通过在js源码中加入debugger的关键字来打点也是支持的(debugger非常有用的关键字!)。
- function timer_tick() {
- count++;
- debugger;
- sys.debug("计数器:" + count);
- ...........
- }
![play play](http://hi.csdn.net/attachment/201009/29/0_1285730867FtAz.gif)
前面不是说到nodejs --debug-brk另外一个的参数吗?究竟有何作用? --debug-brk也是调试的命令,只是在一开始时就是挂起nodejs程序不运行,等待调试器通知才运行。——明显与--debug边运行代码边监听调试的不同。为了避免过多的钻“牛角尖”,还是让用户们自己来试试这个参数吧:)
前面说到调试界面不以独立的C/C++程序提供,其实一方面可以很轻松地嫁接这个调试模块的到C/C++项目中。因为属于高级话题的部分,限水平和能力的缘故就不展开讨论了(可留意一下ry原文)。
结语:有了V8和Eclispe远程调试的可靠保障,nodejs的发展会越来越体现成熟,——让我们投入到美丽的SSJS世界中去吧!