轉(zhuǎn):http://www.tuicool.com/articles/Fzyaa2
新學(xué)習(xí)一種技術(shù)愧旦,肯定會(huì)遇到很多坑聊闯,我們需要找到這些坑宙彪,弄清楚這些坑出現(xiàn)的原因和其中的原理。這種操作就叫做調(diào)試贝淤。
程序調(diào)試的方法和工具多種多樣旺韭,在這里我總結(jié)一下我在學(xué)習(xí)nodejs的過程中,學(xué)到的和用到的調(diào)試方法。
log
在JavaScript代碼中直接console.log厂庇,可以在控制臺(tái)中打印信息。但是這樣的功能太單調(diào)输吏,項(xiàng)目中模塊很多权旷,功能繁雜,如果沒有一個(gè)約定好的console.log方法贯溅,很容易就導(dǎo)致打印的信息十分雜亂拄氯,可讀性很差。
nodejs有一個(gè)debug模塊它浅,提供:
定義log模塊译柏,選擇特定模塊log輸出
模塊文字顏色高亮
log時(shí)間記錄
輸出log到文件等功能
首先
npm init、npm install debug --save ?新建一個(gè)nodejs項(xiàng)目并安裝debug模塊
然后新建
app.js
vardebug=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);
上面兩個(gè)文件中分別創(chuàng)建了 mydebug:http ?和 mydebug:work 兩個(gè)log模塊姐霍,在啟動(dòng)項(xiàng)目的時(shí)候可以配置要打印的log模塊鄙麦,這個(gè)配置是支持通配符匹配的
在linux中啟動(dòng):DEBUG=mydebug:* node app.js在windows中啟動(dòng)setDEBUG=mydebug:* & node app.js
這樣就可以看到不同模塊的日志打印了,同時(shí)也可以看到日志輸出時(shí)間镊折。
在瀏覽器中訪問 localhost:3000 也可以看到打印出的訪問信息
此外debug模塊還提供把日志輸出到文件的功能
setDEBUG=mydebug:*? &? node app.js mydebug:work>debug.log
nodejs debug模塊文檔:https://github.com/visionmedia/debug
debug
光有l(wèi)og還不夠胯府,當(dāng)程序出現(xiàn)問題時(shí)通過log可以定位到錯(cuò)誤位置,但是當(dāng)我們想查看錯(cuò)誤現(xiàn)場的變量時(shí)恨胚,log就無能為力了骂因,一般情況下我們不會(huì)把所有的變量都打印出來。此時(shí)就需要斷點(diǎn)的功能了赃泡,在程序里邊打上斷點(diǎn)寒波,直接定位到錯(cuò)誤位置,分析錯(cuò)誤現(xiàn)場確認(rèn)錯(cuò)誤原因急迂。
nodejs內(nèi)部提供一個(gè)debug機(jī)制影所,可以讓程序進(jìn)入debug模式,供開發(fā)者一步一步分析代碼發(fā)現(xiàn)問題僚碎。
共有3中啟動(dòng)參數(shù)可以讓程序進(jìn)入debug模式
nodedebugapp.jsnode --debugapp.jsnode --debug-brk app.js
3種模式在調(diào)試形式上有一定區(qū)別猴娩。
node debug app.js
1.這種方式啟動(dòng)程序,程序會(huì)進(jìn)入debug模式勺阐,并運(yùn)行到啟動(dòng)文件的第1行就停止卷中,等待開發(fā)者下發(fā)往下走的命令
2.這種方式啟動(dòng)程序,直接在當(dāng)前cmd中進(jìn)入調(diào)試模式
node --debug app.js
1.這種方式啟動(dòng)程序渊抽,程序會(huì)進(jìn)入debug模式蟆豫,并運(yùn)行完所有代碼。這種啟動(dòng)方式往往用于程序啟動(dòng)的過程中不需要調(diào)試懒闷,通過觸發(fā)時(shí)間進(jìn)入回調(diào)函數(shù)的情況十减,比如在某個(gè)http請(qǐng)求中打上斷點(diǎn)栈幸,等待客戶端訪問后進(jìn)入斷點(diǎn)
2.這種方式啟動(dòng)程序,會(huì)開啟一個(gè)TCP的端口監(jiān)聽帮辟,在本cmd中不進(jìn)入調(diào)試模式速址,需要另外開啟終端用node debug 命令連接調(diào)試端口
命令為 node debug localhost debug端口
或者 ? node debug p node進(jìn)程id
node --debug-brk app.js
1.這種方式啟動(dòng)程序,程序會(huì)進(jìn)入debug模式由驹,但是不會(huì)運(yùn)行代碼芍锚,直到有一個(gè)終端連接到了debug端口,才開始執(zhí)行代碼蔓榄,并在第1行進(jìn)入斷點(diǎn)
2.這種方式啟動(dòng)程序并炮,會(huì)開啟一個(gè)TCP的端口監(jiān)聽,在本cmd中不進(jìn)入調(diào)試模式甥郑,需要另外開啟終端用node debug 命令連接調(diào)試端口
進(jìn)入debug模式后逃魄,可以通過一些命令來設(shè)置斷點(diǎn)、取消斷點(diǎn)以及控制程序執(zhí)行流程
命令文檔:https://nodejs.org/api/debugger.html#debugger_commands_reference
流程控制相關(guān)
cont,c- Continue execution
next,n- Step next
step,s- Step in
out,o- Step out
pause- Pause running code (like pause button in Developer Tools)
斷點(diǎn)設(shè)置取消相關(guān)
setBreakpoint(),sb()- Set breakpoint on current line
setBreakpoint(line),sb(line)- Set breakpoint on specific line
setBreakpoint('fn()'),sb(...)- Set breakpoint on a first statement in functions body
setBreakpoint('script.js', 1),sb(...)- Set breakpoint on first line of script.js
clearBreakpoint('script.js', 1),cb(...)- Clear breakpoint in script.js on line 1
變量查看相關(guān)
backtrace,bt- Print backtrace of current execution frame
list(5)- List scripts source code with 5 line context (5 lines before and after)
watch(expr)- Add expression to watch list
unwatch(expr)- Remove expression from watch list
watchers- List all watchers and their values (automatically listed on each breakpoint)
repl- Open debugger's repl for evaluation in debugging script's context
repl模式下可以輸入變量名查看變量內(nèi)容
node debug
從第一行代碼開始進(jìn)入斷點(diǎn)澜搅,命令n進(jìn)入下一行
node --debug
cmd1 ?開啟調(diào)試端口
cmd2 ? 連接調(diào)試端口
設(shè)置斷點(diǎn)嗅钻,取消斷點(diǎn)
cmd1 過了一分鐘才繼續(xù)打印
用進(jìn)程id的方式連接調(diào)試模塊
上圖可以看到pid為4436
repl模式
調(diào)試相關(guān)的工具和模塊
上面的調(diào)試過程還是略顯麻煩,有一些工具和node模塊可以用來輔助調(diào)試店展。
supervisor
supervisor是一個(gè)node模塊,用來啟動(dòng)node項(xiàng)目秃流。
supervisor可以監(jiān)控一些文件赂蕴,當(dāng)這些文件發(fā)生變化時(shí)自動(dòng)刷新程序,不用重新啟動(dòng)node程序舶胀。
當(dāng)程序崩潰時(shí)概说,supervisor會(huì)重新啟動(dòng)程序。
還有其他的一些配置嚣伐,可以在supervisor文檔中看到https://github.com/petruisfan/node-supervisor/
安裝supervisor
npminstall -g supervisor
監(jiān)控work.js的變化并啟動(dòng)node程序
把work中的debug信息修改一下
在任務(wù)管理器中結(jié)束app.js的node進(jìn)程糖赔,可以看到supervisor自動(dòng)重啟了app.js的進(jìn)程
webstorm
webstorm提供了比較方便的debug工具
在菜單中 ?run-debug-app.js
可以直接在行號(hào)的地方點(diǎn)擊,打上斷點(diǎn)
瀏覽器訪問 localhost:3000轩端,進(jìn)入斷點(diǎn)
可以看到webstorm提供的一些調(diào)試工具
實(shí)際上webstorm的調(diào)試功能也是基于 --debug-brk來實(shí)現(xiàn)的放典,使用了63797端口來調(diào)試
node-inspector
如果不喜歡webstorm的調(diào)試工具,還可以使用我們熟悉的chrome調(diào)試工具來調(diào)試node代碼基茵,不過需要安裝一個(gè)node模塊——node-inspector
npminstall -g node-inspector
安裝完成后奋构,開啟一個(gè)node調(diào)試端口 12345
然后新開一個(gè)cmd,開始一個(gè)node-inspector調(diào)試服務(wù)拱层,連接到剛剛開啟的調(diào)試端口
根據(jù)提示訪問地址弥臼,即可使用我們比較熟悉的chrome的調(diào)試工具來調(diào)試nodejs代碼
調(diào)試的技巧有很多,很多細(xì)節(jié)問題都需要不同的調(diào)試技巧來實(shí)現(xiàn)根灯,以后用到新的了再補(bǔ)充吧~