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代码中进一步的调试吗?例如打点、步进、监视等的调试基本操作内容……在下一篇中将为大家作介绍!

现在正式进入要调试程序肯定要有调试代码。下面就是我们第一个测试的代码,很小的行数:

 

[javascript] view plaincopy
  1. var sys = require('sys');  
  2. // 此乃计数器变量,Suspend(中断挂起)期间可以观察该变量的变化。  
  3. var count = 0;  
  4. sys.debug("开始进行调试……");  
  5. function timer_tick() {  
  6.     count++;  
  7.     sys.debug("计数器:" + count);  
  8.     if (count === 10) {  
  9.         count += 1000;  
  10.         sys.debug("能在这里打点吗?错过10后不行啦");  
  11.     }  
  12.     setTimeout(timer_tick, 1000);  
  13. }  
  14. 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)下呢?留意一下debugView 是否被选中即可,在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)); ,结果如下:

 

[javascript] view plaincopy
  1. //输出结果    
  2. {   
  3.    print:[Function],   
  4.    puts:[Function],   
  5.    debug:[Function],   
  6.    error:[Function],   
  7.    inspect:[Function],   
  8.    p:[Function],   
  9.    log:[Function],   
  10.    exec:[Function],   
  11.    inherits:[Function]   
  12. }   

 

再回到Eclipse调试视图中。如下图表明链接nodejs成功,可以进行相关的调试工作。

切换至Project Explorer标签页,这里列出了所有的require()包文件和nodejs.exe <文件名>所指定的主程序文件,都是JavaScript(*.js)文件。

files

我们双击打开程序文件dbgtest.js,即可打开源码:

source

在行数上方双击那一行,就是一个打点的工作(breakpoint),程序随即被挂起,暂停工作,调试器中显示当地变量等的信息供用户观察与进一步应用。如图我们在第8行打了一个点:

breakpoint

首次使用Eclipse的调试界面感觉可能有些别扭,这没有关系。如果不太习惯,使用多几次就好。调试的基本内容大抵是那几回事。例如,你可以步进跟踪代码(step into,快捷键F5,但注意一点,对于步进require可能会crash挂掉,这也是情有可原的,require()是加载包的特殊方法)。下图则是调出watch的功能。

watch

当然,通过在js源码中加入debugger的关键字来打点也是支持的(debugger非常有用的关键字!)。

 

[javascript] view plaincopy
  1. function timer_tick() {  
  2.     count++;  
  3.     debugger;  
  4.     sys.debug("计数器:" + count);  
  5.     ...........  
  6. }  
恢复nodejs程序的运行,就要按play 绿色的箭头来恢复,快捷键是F8;(现在处于暂停所以中间的按钮是灰色;)红色按钮就是断开链接。另外如果至于如何关闭nodejs进程?据作者惯用的方式,就是在dos/win的命令行下ctrl+c强行退出即可。

 

前面不是说到nodejs --debug-brk另外一个的参数吗?究竟有何作用? --debug-brk也是调试的命令,只是在一开始时就是挂起nodejs程序不运行,等待调试器通知才运行。——明显与--debug边运行代码边监听调试的不同。为了避免过多的钻“牛角尖”,还是让用户们自己来试试这个参数吧:)

前面说到调试界面不以独立的C/C++程序提供,其实一方面可以很轻松地嫁接这个调试模块的到C/C++项目中。因为属于高级话题的部分,限水平和能力的缘故就不展开讨论了(可留意一下ry原文)。

结语:有了V8和Eclispe远程调试的可靠保障,nodejs的发展会越来越体现成熟,——让我们投入到美丽的SSJS世界中去吧!

posted @ 2012-07-12 14:24  orlla  阅读(817)  评论(0编辑  收藏  举报