新聞中心
Node.js是一個JavaScript運行時,基于與Google Chrome瀏覽器中使用的相同的V8引擎。它通常用于構(gòu)建跨平臺的服務(wù)器端和終端應(yīng)用程序。Node.js在過去十年中變得越來越流行,因為它易于安裝、實用、速度快,并且允許客戶端Web開發(fā)人員在其他地方利用他們的技能。

但是,軟件開發(fā)仍然是一項復(fù)雜的任務(wù),您的Node.js代碼有時會失敗。本教程演示了各種工具來幫助調(diào)試應(yīng)用程序并找出問題的原因。
Tips:Deno是一個替代的JavaScript運行時。它與Node.js相似,但更新,它消除了一些裂縫和不一致。下面的工具和信息通??梢詰?yīng)用于Deno應(yīng)用程序和Node.js。
調(diào)試概述
“調(diào)試”是修復(fù)軟件缺陷的各種方法的名稱。修復(fù)錯誤通常很簡單。查找錯誤的原因可能要復(fù)雜得多,并且需要花費數(shù)小時的時間。
以下部分描述了您將遇到的三種一般類型的錯誤。
語法錯誤
您的代碼不遵循語言規(guī)則——例如,當(dāng)您省略右括號或拼寫錯誤的語句,如console.lag(x).
一個好的代碼編輯器可以通過以下方式幫助發(fā)現(xiàn)常見問題:
- 對有效或無效語句進行顏色編碼
- 類型檢查變量
- 自動完成函數(shù)和變量名
- 突出顯示匹配的括號
- 自動縮進代碼塊
- 檢測無法訪問的代碼
- 重構(gòu)雜亂的功能
VS Code和Atom等免費編輯器對Node.js、JavaScript和TypeScript(可轉(zhuǎn)換為JavaScript)提供了很好的支持。在保存和測試代碼之前,通??梢园l(fā)現(xiàn)基本語法問題。
像ESLint這樣的代碼linter也會報告語法錯誤、縮進錯誤和未聲明的變量。ESLint是一個Node.js工具,您可以通過以下方式全局安裝:
npm i eslint -g
您可以使用以下命令從命令行檢查JavaScript文件:
eslint mycode.js
…但是使用編輯器插件更容易,例如用于VS Code的ESLint或用于Atom的 linter-eslint,它們會在您鍵入時自動驗證代碼:
VS Code中的ESlint
邏輯錯誤
您的代碼運行但未按預(yù)期工作。例如,用戶在請求時沒有注銷;報告顯示不正確的數(shù)字;數(shù)據(jù)未完全保存到數(shù)據(jù)庫中;等等。
邏輯錯誤可能由以下原因引起:
- 使用錯誤的變量
- 不正確的條件,例如,
if (a > 5)而不是if (a < 5) - 未能考慮運算符優(yōu)先級的計算,例如,
1+2*3結(jié)果為7而不是9。
運行時(或執(zhí)行)錯誤
錯誤只有在應(yīng)用程序執(zhí)行時才會變得明顯,這通常會導(dǎo)致崩潰。運行時錯誤可能由以下原因引起:
- 除以已設(shè)置為零的變量
- 試圖訪問不存在的數(shù)組項
- 嘗試寫入只讀文件
盡管以下開發(fā)技術(shù)可以提供幫助,但邏輯和運行時錯誤更難發(fā)現(xiàn):
您仍然會遇到Node.js錯誤,但以下部分描述了定位該難以捉摸的錯誤的方法。
設(shè)置適當(dāng)?shù)腘ode.js環(huán)境變量
在主機操作系統(tǒng)中設(shè)置的環(huán)境變量可以控制Node.js應(yīng)用程序和模塊設(shè)置。最常見的是NODE_ENV,通常在調(diào)試時設(shè)置為開發(fā),或者在實時服務(wù)器上運行時設(shè)置為生產(chǎn)。在macOS或Linux上設(shè)置環(huán)境變量:
NODE_ENV=development
或在(經(jīng)典)Windows命令提示符下:
set NODE_ENV=development
或Windows Powershell:
$env:NODE_ENV="development"
在流行的Express.js框架中,將NODE_ENV設(shè)置為development會禁用模板文件緩存并輸出詳細(xì)的錯誤消息,這在調(diào)試時可能會有所幫助。其他模塊可能提供類似的功能,您可以在應(yīng)用程序中添加NODE_ENV條件,例如
// running in development mode?
const devMode = (process.env.NODE_ENV !== 'production');
if (devMode) {
console.log('application is running in development mode');
}
您還可以使用Node的util.debuglog方法有條件地輸出錯誤消息,例如
import { debuglog } from 'util';
const myappDebug = debuglog('myapp');
myappDebug('log something');
此應(yīng)用程序僅在NODE_DEBUG設(shè)置為 myapp 或 * 或 my* 等通配符時才會輸出日志消息。
使用Node.js命令行選項
節(jié)點腳本通常使用node后跟入口腳本的名稱來啟動:
node app.js
您還可以設(shè)置命令行選項來控制各種運行時方面。用于調(diào)試的有用標(biāo)志包括:
--check語法檢查腳本而不執(zhí)行--trace-warnings當(dāng)JavaScript Promises未解析或拒絕時輸出堆棧跟蹤--enable-source-maps使用TypeScript等轉(zhuǎn)譯器時顯示源映射--throw-deprecation使用已棄用的Node.js功能時發(fā)出警告--redirect-warnings=file將警告輸出到文件而不是stderr--trace-exit調(diào)用時輸出堆棧跟蹤process.exit()。
將消息輸出到控制臺
輸出控制臺消息是調(diào)試Node.js應(yīng)用程序的最簡單方法之一:
console.log(`someVariable: ${ someVariable }`);
很少有開發(fā)人員意識到還有許多其他控制臺方法:
| 控制臺方法 | 描述 |
|---|---|
.log(msg) |
標(biāo)準(zhǔn)控制臺消息 |
.log('%j', obj) |
將對象輸出為緊湊的JSON字符串 |
.dir(obj, opt) |
漂亮打印對象屬性 |
.table(obj) |
以表格格式輸出數(shù)組和對象 |
.error(msg) |
錯誤信息 |
.count(label) |
增加一個命名的計數(shù)器和輸出 |
.countReset(label) |
重置命名計數(shù)器 |
.group(label) |
縮進一組消息 |
.groupEnd(label) |
終止一個組 |
.time(label) |
啟動一個命名的計時器 |
.timeLog(label) |
報告經(jīng)過的時間 |
.timeEnd(label) |
停止一個命名的計時器 |
.trace() |
輸出堆棧跟蹤(所有函數(shù)調(diào)用的列表) |
.clear() |
清除控制臺 |
console.log()還接受逗號分隔值的列表:
let x = 123;
console.log('x:', x);
// x: 123
…盡管ES6解構(gòu)提供了類似的輸出,但花費更少:
console.log({ x });
// { x: 123 }
console.dir()命令以與util.inspect()相同的方式漂亮地打印對象屬性:
console.dir(myObject, { depth: null, color: true });
控制臺爭議
一些開發(fā)人員聲稱您永遠(yuǎn)不應(yīng)該使用console.log(),因為:
- 您正在更改代碼并且可能會更改某些內(nèi)容或忘記刪除它,并且
- 當(dāng)有更好的調(diào)試選項時,就沒有必要了。
不要相信任何聲稱他們從未使用過的人console.log()!記錄既快又臟,但每個人都在某個時候使用它。使用您喜歡的任何工具或技術(shù)。修復(fù)一個錯誤比你找到它的方法更重要。
使用第三方日志系統(tǒng)
第三方日志系統(tǒng)提供更復(fù)雜的功能,例如消息傳遞級別、詳細(xì)程度、排序、文件輸出、分析、報告等。流行的解決方案包括cabinet、loglevel、morgan、pino、signale、storyboard、tracer和winston。
使用V8檢查器
V8 JavaScript引擎提供了一個可以在Node.js中使用的調(diào)試客戶端。使用節(jié)點檢查啟動應(yīng)用程序,例如
node inspect app.js
調(diào)試器在第一行暫停并顯示debug>提示:
$ node inspect .\mycode.js
< Debugger listening on ws://127.0.0.1:9229/143e23fb
< For help, see: https://nodejs.org/en/docs/inspector
<
ok
< Debugger attached.
<
Break on start in mycode.js:1
> 1 const count = 10;
2
3 for (i = 0; i < counter; i++) {
debug>
輸入幫助以查看命令列表。您可以通過輸入以下內(nèi)容逐步完成應(yīng)用程序:
- cont 或 c : 繼續(xù)執(zhí)行
- next 或 n:運行下一個命令
- step 或 s:進入被調(diào)用的函數(shù)
- out 或 o : 跳出函數(shù)并返回調(diào)用語句
- pause:暫停正在運行的代碼
- watch(‘myvar’) : 觀察一個變量
- setBreakPoint() 或 sb():設(shè)置斷點
- restart:重新啟動腳本
- .exit 或 Ctrl | Cmd + D:退出調(diào)試器
誠然,這種調(diào)試選項既費時又笨拙。僅在沒有其他選項時使用它,例如當(dāng)您在遠(yuǎn)程服務(wù)器上運行代碼并且無法從其他地方連接或安裝其他軟件時。
使用Chrome瀏覽器調(diào)試Node.js代碼
上面使用的Node.js檢查選項啟動了一個Web Socket服務(wù)器,它在localhost端口9229上進行偵聽。它還啟動了一個基于文本的調(diào)試客戶端,但也可以使用圖形客戶端——例如內(nèi)置于Google Chrome和基于Chrome的客戶端Chromium、Edge、Opera、Vivaldi和Brave等瀏覽器。
要調(diào)試典型的Web應(yīng)用程序,請使用–inspect選項啟動它以啟用V8調(diào)試器的Web Socket服務(wù)器:
node --inspect index.js
筆記:
- index.js被假定為應(yīng)用程序的入口腳本。
- 確保您使用
--inspect雙破折號以確保您不會啟動基于文本的調(diào)試器客戶端。 - 如果您想在文件更改時自動重新啟動應(yīng)用程序,您可以使用nodemon而不是node。
默認(rèn)情況下,調(diào)試器只接受來自本地機器的傳入連接。如果您在其他設(shè)備、虛擬機或Docker容器上運行應(yīng)用程序,請使用:
node --inspect=0.0.0.0:9229 index.js
節(jié)點檢查選項
您還可以使用--inspect-brk而不是--inspect在第一行停止處理(設(shè)置斷點),以便您可以從頭開始逐步執(zhí)??行代碼。
打開基于Chrome的瀏覽器并chrome://inspect在地址欄中輸入以查看本地和聯(lián)網(wǎng)設(shè)備:
Chrome檢查工具
如果您的Node.js應(yīng)用程序未顯示為Remote Target,則:
- 單擊Open dedicated DevTools for Node并選擇地址和端口,或者
- 檢查Discover network targets,單擊Configure,然后添加運行它的設(shè)備的IP地址和端口。
單擊Target的inspect鏈接以啟動DevTools調(diào)試器客戶端。使用DevTools進行客戶端代碼調(diào)試的任何人都應(yīng)該熟悉這一點:
Chrome開發(fā)工具
切換到Sources面板。您可以通過點擊Cmd | Ctrl + P打開任何文件并輸入其文件名(例如index.js)。
但是,將項目文件夾添加到工作區(qū)更容易。這允許您直接從DevTools加載、編輯和保存文件(您是否認(rèn)為這是一個好主意是另一回事?。?/p>
您現(xiàn)在可以從左側(cè)目錄樹加載文件:
Chrome DevTools Sources面板
單擊任何行號以設(shè)置由藍(lán)色標(biāo)記表示的斷點。
調(diào)試基于斷點。這些指定調(diào)試器應(yīng)在何處暫停程序執(zhí)行并顯示程序的當(dāng)前狀態(tài)(變量、調(diào)用堆棧等)
您可以在用戶界面中定義任意數(shù)量的斷點。另一種選擇是放置一個調(diào)試器;聲明到您的代碼中,當(dāng)附加調(diào)試器時停止。
加載并使用您的Web應(yīng)用程序到達設(shè)置斷點的語句。在此處的示例中,http://localhost:3000/在任何瀏覽器中打開,DevTools將在第44行停止執(zhí)行:
Chrome斷點
右側(cè)面板顯示:
- 一排操作圖標(biāo)(見下文)。
- Watch窗格允許您通過單擊+圖標(biāo)并輸入變量名稱來監(jiān)視變量。
- Breakpoints窗格顯示所有斷點的列表,并允許啟用或禁用它們。
- Scope窗格顯示所有本地、模塊和全局變量的狀態(tài)。您將最常檢查此窗格。
- Call Stack窗格顯示了為達到這一點而調(diào)用的函數(shù)的層次結(jié)構(gòu)。
Paused on breakpoint上方顯示了一排操作圖標(biāo):
Chrome斷點圖標(biāo)
從左到右,它們執(zhí)行以下操作:
- resume execution : 繼續(xù)處理直到下一個斷點
- step over:執(zhí)行下一個命令,但停留在當(dāng)前代碼塊內(nèi)——不要跳轉(zhuǎn)到它調(diào)用的任何函數(shù)
- step into : 執(zhí)行下一個命令并根據(jù)需要跳轉(zhuǎn)到任何函數(shù)
- step out:繼續(xù)處理到函數(shù)結(jié)束,返回調(diào)用命令
- step : 與step into類似,只是它不會跳轉(zhuǎn)到異步函數(shù)
- deactivate所有斷點
- pause on exceptions:發(fā)生錯誤時停止處理。
條件斷點
有時有必要對斷點進行更多控制。假設(shè)您有一個完成1,000次迭代的循環(huán),但您只對最后一次的狀態(tài)感興趣:
for (let i = 0; i < 1000; i++) {
// set breakpoint here
}
與其單擊resume execution 999次,不如右鍵單擊該行,選擇Add conditional breakpoint,然后輸入一個條件,例如i = 999:
Chrome條件斷點
Chrome以黃色而不是藍(lán)色顯示條件斷點。在這種情況下,斷點僅在循環(huán)的最后一次迭代時觸發(fā)。
日志點
日志點無需任何代碼即可有效實現(xiàn)console.log()!當(dāng)代碼執(zhí)行任何一行時,可以輸出一個表達式,但它不會停止處理,這與斷點不同。
要添加日志點,請右鍵單擊任意行,選擇Add log point,然后輸入表達式,例如'loop counter i', i:
Chrome日志點
DevTools控制臺輸出loop counter i: 0到loop counter i: 999上例中。
使用VS Code調(diào)試Node.js應(yīng)用程序
VS Code或Visual Studio Code是來自Microsoft的免費代碼編輯器,在Web開發(fā)人員中很受歡迎。該應(yīng)用程序可用于Windows、macOS和Linux,并使用Electron框架中的Web技術(shù)開發(fā)。
VS Code支持Node.js并具有內(nèi)置的調(diào)試客戶端。大多數(shù)應(yīng)用程序無需任何配置即可調(diào)試;編輯器會自動啟動調(diào)試服務(wù)器和客戶端。
打開啟動文件(例如index.js),激活Run and Debug窗格,單擊Run and Debug按鈕,然后選擇Node.js環(huán)境。單擊任意行以激活顯示為紅色圓圈圖標(biāo)的斷點。然后,像以前一樣在瀏覽器中打開應(yīng)用程序——VS Code在到達斷點時停止執(zhí)行:
VS代碼斷點
Variables、Watch、Call Stack和Breakpoints窗格與Chrome DevTools中顯示的相似。Loaded Scripts窗格顯示已加載的腳本,盡管許多腳本是Node.js內(nèi)部的。
操作圖標(biāo)工具欄允許您:
- resume execution : 繼續(xù)處理直到下一個斷點
- step over:執(zhí)行下一個命令,但停留在當(dāng)前函數(shù)內(nèi)——不要跳轉(zhuǎn)到它調(diào)用的任何函數(shù)
- step into:執(zhí)行下一個命令并跳轉(zhuǎn)到它調(diào)用的任何函數(shù)
- step out:繼續(xù)處理到函數(shù)結(jié)束,返回調(diào)用命令
- restart應(yīng)用程序和調(diào)試器
- stop應(yīng)用程序和調(diào)試器
與Chrome DevTools一樣,您可以右鍵單擊任意行以添加Conditional breakpoints和Log points。
有關(guān)詳細(xì)信息,請參閱Visual Studio Code中的調(diào)試。
VS Code高級調(diào)試配置
如果您想在另一臺設(shè)備、虛擬機上調(diào)試代碼,或者需要使用其他啟動選項(例如nodemon),則可能需要進一步的VS Code配置。
VS Code將調(diào)試配置存儲在項目目錄.vscode中的launch.json文件中。打開Run and Debug窗格,單擊create a launch.json file,然后選擇Node.js環(huán)境來生成此文件。提供了一個示例配置:
VS Code調(diào)試器配置
可以將任意數(shù)量的配置設(shè)置定義為"configurations"數(shù)組中的對象。單擊Add Configuration…并選擇適當(dāng)?shù)倪x項。
單個Node.js配置可以:
例如,要定義nodemon配置,請選擇Node.js: Nodemon Setup并在必要時更改“program”入口腳本:
{
// custom configuration
"version": "0.2.0",
"configurations": [
{
"console": "integratedTerminal",
"internalConsoleOptions": "neverOpen",
"name": "nodemon",
"program": "${workspaceFolder}/index.js",
"request": "launch",
"restart": true,
"runtimeExecutable": "nodemon",
"skipFiles": [
"/**"
],
"type": "pwa-node"
}
]
}
保存launch.json文件,nodemon (配置“name”)出現(xiàn)在“Run and Debug”窗格頂部的下拉列表中。單擊綠色運行圖標(biāo)開始使用該配置并使用nodemon啟動應(yīng)用程序:
使用nodemon進行VS Code調(diào)試
和以前一樣,您可以添加斷點、條件斷點和日志點。主要區(qū)別在于,當(dāng)文件被修改時,nodemon會自動重啟你的服務(wù)器。
有關(guān)詳細(xì)信息,請參閱VS Code啟動配置。
以下VS Code擴展還可以幫助您調(diào)試托管在遠(yuǎn)程或隔離服務(wù)器環(huán)境中的代碼:
- Remote — Containers:連接到在Docker容器中運行的應(yīng)用程序
- Remote — SSH:連接到遠(yuǎn)程服務(wù)器上運行的應(yīng)用程序
- Remote — WSL:連接到在Linux的Windows子系統(tǒng) (WSL) 上運行的應(yīng)用程序。
其他Node.js調(diào)試選項
Node.js調(diào)試指南為一系列文本編輯器和IDE提供建議,包括Visual Studio、JetBrains WebStorm、Gitpod和Eclipse 。Atom提供了一個node-debug擴展,它將Chrome DevTools調(diào)試器集成到編輯器中。
一旦您的應(yīng)用程序上線,您可以考慮使用商業(yè)調(diào)試服務(wù),例如LogRocket和Sentry.io,它們可以記錄和回放真實用戶遇到的客戶端和服務(wù)器錯誤。
小結(jié)
從歷史上看,JavaScript調(diào)試一直很困難,但在過去十年中已經(jīng)有了巨大的改進。選擇與為其他語言提供的選擇一樣好——如果不是更好的話。
使用任何實用的工具來定位問題。console.log()用于快速查找bug沒有任何問題,但對于更復(fù)雜的問題,Chrome DevTools或VS Code可能更可取。這些工具可以幫助您創(chuàng)建更強大的代碼,并且您將花費更少的時間來修復(fù)錯誤。
網(wǎng)站名稱:如何使用多種工具調(diào)試Node.js代碼
地址分享:http://www.5511xx.com/article/dppjpij.html


咨詢
建站咨詢
