新學習一種技術,肯定會遇到很多坑,我們需要找到這些坑,弄清楚這些坑出現的原因和其中的原理。這種操作就叫做除錯。
程式除錯的方法和工具多種多樣,在這裡我總結一下我在學習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程式。
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程式碼
除錯的技巧有很多,很多細節問題都需要不同的除錯技巧來實現,以後用到新的了再補充吧~