JavaScript 斷點調試技巧

大家好,我是若川。最近組織了源碼共度活動:1個月,200+人,一起讀了4周源碼,參與的小伙伴都表示收獲很大。如果感興趣可以點擊鏈接掃碼加我微信 ruochuan12。之前推薦過很多次調試文章,說明調試的重要性,重要的是自己動手實踐。前端容易忽略的 debugger 調試技巧、寫 Node.js 代碼,從學會調試開始


為什么要使用 debugger

這篇文章將介紹如何使用斷點來進行 JavaScript 調試。在讀這篇文章之前,需要問一個問題:為什么要使用斷點來進行調試?

我們首先需要認可使用斷點的是必要的,否則下文介紹的所有斷點調試方法都會是廢話。console.log 是前端開發最常用的調試手段,它簡單直接解決一部分問題。但當遇到十分復雜的問題,console.log 就會變得不趁手。比如:

  • 一個邏輯復雜的算法

    如果你刷過 leetcode 一定深有體會,算法某個測試用例報錯了,有時很難光靠目測找出有問題的那個方法。

  • 一個復現步驟十分繁瑣的bug。

    花了10分鐘好不容易復現了,但是只跟蹤到某行代碼,需要第二次添加 log 才能繼續尋找問題。查看log -> 添加log -> 查看log... 這個過程重復幾遍,今天剩下的磚就搬不完了。

  • 一段運行流程冗長的代碼

  • 一段沒有注釋、起名隨意的代碼

  • server 端代碼

    有 nodejs 服務端開發經驗的同學相信有過在 postman 和 ide 之間反復橫跳的經歷,如果光靠 log,對于一個巨大的復雜對象,控制臺是不好查看全貌的。如果一個接口還涉及到數據庫增刪、第三方依賴,那么復原上一次請求造成的后果也是一件痛苦的事情。

在這些情況下,斷點調試是非常有價值的,將 debug 的時間復雜度從 O(n) 降到 O(1),讓搬磚更快樂。

這是文章的內容大綱:

  • Chrome debugger 基本用法

  • VS Code 調試 SPA 應用

  • Chrome 調試 Nodejs

  • VS Code 調試 Nodejs

Chrome debugger 基本用法

最簡單的斷點調試,就是在代碼中加一句 debugger,然后到瀏覽器中刷新頁面,這時候瀏覽器就會在 debugger 語句那停止執行。

為了方便理解,引入一個簡單例子,在一個文件夾中創建 index.htmlindex.js,然后在 index.html 中引入 index.jsindex.js 內容如下:

//?國際慣例,hello world。
const?greet?=?()?=>?{const?greeting?=?"hello?debugger";//?瀏覽器執行到這里將會暫停debuggerconsole.log(greeting);
};greet();console.log("js?evaluation?done");

執行命令:

npm?i?-g?serve
serve?.

然后訪問 http://localhost:5000并打開開發者工具。

這時候我們的 hello world 斷點就打上了,就像這樣:

d8090eb4-4a1f-4dfb-bf30-c08c762d66ad

圖中分為四個區域,藍色區域用于文件選擇,Page 一欄是指當前頁面中的 JS 文件,Filesystem 會顯示我們系統中的文件。通常我們使用 Page

粉色是代碼的行號和內容。代碼的行號處可以通過點擊來添加新的斷點,再次點擊后取消。

黃色區域用于控制代碼的執行,只需要掌握前四個按鈕的含義,就可以應付絕大多數場景。按鈕1是讓代碼繼續執行(resume),如果遇到下一個斷點就會再次中斷執行。按鈕2可以讓瀏覽器執行當前行(圖中是第3行),然后在下一行中斷代碼,按鈕3是進入當前函數,查看函數具體內容。假設我們當前停在第7行 greet() ,點擊按鈕3就會進入 greet 方法中(也就是第2行)。如果不想再看 greet 方法了,就點擊按鈕4,跳出這個方法,回到第8行。

綠色區域可以查看變量的內容和當前的調用棧。

debugger 是最簡單粗暴的打斷點方式,但是需要修改我們的代碼。需要注意的是,上線前必須刪除這些語句。也可以通過配置 webpack 來自動去除。不過終究還是有些不方便,所以我們來看下如何通過 vscode 來簡化打斷點的方式。

VS Code 調試 SPA 應用

首先我們使用 Vite 來創建一個 Vue 應用用于演示(React步驟類似)。

#?創建?vut-ts?應用
npm?init?vite
cd?hello-vite
npm?install
#?調用?VS?Code?cli?打開項目,
#?或者手動在 VS Code 打開。
code?.
npm?run?dev

然后在 VS Code 中新建一個文件 .vscode/launch.json,填入這些內容:

{"version":?"0.2.0","configurations":?[{"type":?"pwa-chrome","request":?"launch","name":?"Launch?Vue?project",//?這里填入項目的訪問地址"url":?"http://localhost:3000","webRoot":?"${workspaceFolder}"},]
}

然后使用 cmd+q 退出你正在運行的 Chrome(這步很重要,不能跳過),按 f5 啟動 VS Code 的調試功能。VS Code 就會幫你啟動一個 Chrome 窗口,并訪問上述配置的中的 url。這時候我們的斷點就生效了,可以一步一步地控制代碼的運行,找出 bug 來源。

7f962a01-e7eb-4ca8-9888-68177fbb07dd

這里有一個實用的小技巧,就是在 BREAKPOINTS 中,把 Uncaught Exceptions 勾上,這樣在代碼報錯的地方,就會自動中斷執行。當我們遇到一個報錯時,采用這個方法可以省去定位問題代碼的時間。

402686f5-4076-43e9-b345-6814fd89ae45

另外我們可以發現,在 VS Code 斷點生效時,Chrome Devtools 也會同步這個展示這個斷點。

59038bd1-67aa-4b42-8320-54f718bab48e

在 VS Code 中,調試有兩種模式,分別是 launchattach。由于真正執行代碼的是 Chrome 中的 JS 引擎,所以是否中斷代碼的控制權是在 Chrome 手里的。那為什么 VS Code 的斷點可以控制代碼的中斷呢?是因為 VS Code 通過 devtools-protocol 向 Chrome 發起指令,告訴 Chrome 需要在哪一行代碼暫停執行。這個發送指令的過程,被稱作 attach。而 launch 的過程包含 attach ,即先 launch(啟動) 瀏覽器,然后 attach(附加) 斷點信息。所以 attach 模式是 launch 模式的子集。

聽起來好像 launch 模式會更方便,為我們省去了手動啟動瀏覽器的過程。但是這存在一個問題,如果同時開發多個前端工程會怎樣?每個工程啟動一個調試進程,就會打開多個瀏覽器,那么在多個瀏覽器之間切換就會顯得很麻煩。我們可以使用 attach 模式解決這個問題。

首先我們使用命令行啟動 Chrome。使用命令行的原因是,我們需要給 Chrome 的啟動傳參。

#?運行這條命令前需要cmd+q退出已運行的Chrome
/Applications/Google\?Chrome.app/Contents/MacOS/Google\?Chrome?--remote-debugging-port=9222
#?如果看到這個輸出,說明傳參成功。
DevTools?listening?on?ws://127.0.0.1:9222/devtools/browser/856a3533-ca5c-474f-a0cf-88b7ae94c75b

VS Code 和 Chrome 是通過 websocket 交流,--remote-debugging-port 指定了 websocket 使用的端口。然后我們將 launch.json 文件修改成這樣:

{"version":?"0.2.0","configurations":?[{"type":?"pwa-chrome","request":?"attach","name":?"Vue?Application",//?項目訪問的?url"url":?"http://localhost:3000",// websocket 端口,需要與?--remote-debugging-port 參數保持一致。"port":?9222,"webRoot":?"${workspaceFolder}"},]
}

注意在啟動 VS Code 調試之前,需要在 Chrome 中打開 http://localhost:3000 這個頁面。然后我們在 VS Code 中打上斷點,刷新瀏覽器,代碼就成功停在斷點處了。第二個、第n個工程都可以采用相同的配置,區別是 url 字段要根據項目配置進行修改。

Chrome 調試 Nodejs

上文講的是如何調試頁面,接下來我們聊如何調試 nodejs 應用。首先來一個最容易上手的例子,創建一個 hello world:

//?debug.js?文件
const?greeting?=?'hello?nodejs?debugger'
debugger
console.log(greeting)

然后運行這個文件

node?--inspect-brk?debug.js
Debugger?listening?on?ws://127.0.0.1:9229/b9a6d6bf-baaa-4ad5-8cc6-01eb69e99f0a
For?help,?see:?https://nodejs.org/en/docs/inspector

--inspect-brk 表示運行這個 js 文件的同時,在文件的第一行打上斷點。然后打開 Chrome,進入 Devtools。點擊紅框處的按鈕,就會打開一個 nodejs 專用的調試窗口,并且代碼在第一行中斷了。

074ccabf-1833-4393-8566-52b0a4cf3568

nodejs 調試窗口:

cc3d93a5-d97c-4799-98a2-936dfe18c887

這個方式的實質是,Chrome Devtool 根據 v8引擎的調試協議 向 nodejs 進程發送指令,控制代碼的運行。可以發現,在網頁的調試中,Chrome 是接受指令的一方,而在 nodejs 調試中,Chrome 轉身變為發送指令的一方。所謂從悲慘的乙方華麗轉身成甲方。

node 默認的 websocket 端口是 9229,如果有需要的話(比如端口被占用了),我們可以通過一些方式改變這個端口。

node?--inspect=9228?debug.js
Debugger?listening?on?ws://127.0.0.1:9228/30f21d45-9806-47b8-8a0b-5fb97cf8bb87
For?help,?see:?https://nodejs.org/en/docs/inspector

在我們打開 Devtool 時,Chrome 默認檢查 9229 端口,但當我們改變了端口號后,就需要手動去指定 Chrome 檢查的地址了。點擊下圖中的 Configure 按鈕,輸入 127.0.0.1:9228,然后點擊 Done。這時候 Remote Target 中就會出現 剛才啟動的 node 進程,點擊 inspect 就可以進入調試了。

494fcb5f-b688-4a26-b868-b4c284327afc

使用 VS Code 調試 Nodejs

到此為止,我們已經達成調試 node 的目的,但還有些繁瑣,不夠自動化。我們可以使用 VS Code,來一鍵啟動調試。

用 VS Code 打開剛才的工程,然后在 launch.json 中輸入這些:

{"version":?"0.2.0","configurations":?[{"type":?"pwa-node","request":?"launch","name":?"Launch?Program","skipFiles":?["<node_internals>/**"],//?${file}?的意思是,當我們啟動調試的時候,調試的程序就是當前 focus 的文件。"program":?"${file}"}]
}

這時候切換到 index.js 文件,按 f5 啟動調試程序,當運行到第二行 debugger 語句的時候,就會自動暫停執行。也可以點擊代碼行數的左側來打斷點。

另外,這個配置是支持 TypeScript 的,我們只需要 index.js 重命名為 index.ts,然后正常啟動調試就行。

Conditional Breakpoint 條件斷點

在某些情況下,我們不希望打上的每個斷點都發揮作用,而是在執行到斷點那行,且滿足某個條件再中斷代碼執行。這就是條件斷點。

for (let i = 0; i < 10; i++) {console.log("i", i);
}

比如上面的代碼,假設我們在第二行 console.log 打了斷點,那么這個斷點總計會中斷十次。這往往是我們不希望看到的,可能我們需要的僅僅是其中某一次循環而非所有。這時候可以右鍵點擊并選擇 Add Conditional Breakpoint

eedcb461-24cc-42b4-ab8a-87bc865cb69b

這時會有一個輸入框出現,我們在其中輸入 i === 5

d704077c-c048-47b5-ae0f-7aa88dc54f47

這時候啟動調試,就會跳過 i 為 0 - 4,直接在在 i 為 5 的時候中斷代碼執行。恢復代碼執行后,會略過 i 為 6 - 9 的情況。

Conditional Breakpoint 在調試帶有大量循環和 if else 判斷時極為有用,特別是當某處的邏輯整體上是符合預期的,僅有個別特殊情況的輸出錯誤,使用條件斷點就可以略過這些正常的情況,只在個別特殊情況出現的時候,再中斷執行,供我們查看各個變量是否計算正常。

總結

調試是日常工作中非常重要的能力,因為除了開發新功能外,日常有很大一部分都在調整舊的代碼,處理特別條件下的邏輯錯誤。熟練掌握調試可以很好地提升搬磚幸福感,一個復雜的 bug 卡幾小時,很容易讓人心里崩潰。但也不是說斷點調試是任何情況下都適用的銀彈,簡單的邏輯還是可以愉快地 console.log 的。

文章介紹了使用 Chrome Devtools 和 VS Code 斷點調試的方法,整體上還是更推薦使用 VS Code。launch.json 只需要一次配置,后續都可以 f5 一鍵啟動調試。另外,文中提到的各種 launch.json 文件的配置,都可以使用 VS Code 自帶的工具一鍵生成。只要打開 launch.json,編輯器的右下角就會出現 Add Configuration 按鈕,點擊就可以選擇自己需要添加的調試配置。

最近組建了一個江西人的前端交流群,如果你是江西人可以加我微信?ruochuan12?私信 江西?拉你進群。

推薦閱讀

1個月,200+人,一起讀了4周源碼
我讀源碼的經歷

老姚淺談:怎么學JavaScript?

我在阿里招前端,該怎么幫你(可進面試群)

·················?若川簡介?·················

你好,我是若川,畢業于江西高校。現在是一名前端開發“工程師”。寫有《學習源碼整體架構系列》多篇,在知乎、掘金收獲超百萬閱讀。
從2014年起,每年都會寫一篇年度總結,已經寫了7篇,點擊查看年度總結。
同時,活躍在知乎@若川,掘金@若川。致力于分享前端開發經驗,愿景:幫助5年內前端人走向前列。

識別方二維碼加我微信、拉你進源碼共讀

今日話題

略。歡迎分享、收藏、點贊、在看我的公眾號文章~

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/275484.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/275484.shtml
英文地址,請注明出處:http://en.pswp.cn/news/275484.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

大學生電子設計大賽案例分析_為大學生設計問答平臺—案例研究

大學生電子設計大賽案例分析Dealing with academic-related questions like picking a course, fulfilling a major requirement can be tedious and ineffective when you have to simultaneously balance school work, social activities, and focus on personal growth and …

最新最詳細最簡潔Eclipse調試PHP配置詳解(Xdebug,Zend Debugger)

搬家注&#xff1a;該日志寫于2011 年 04 月 07 日&#xff0c;Eclipse&#xff0c;PHP等版本號很多&#xff0c;更新也比較快&#xff0c;請注意文章中的版本。本文不一定幫您解決問題&#xff0c;但能給您一些解決問題的思路及一些概念。 最近開始做SRTP項目WebOS&#xff0c…

按鍵精靈易語言c,求助(把按鍵精靈的源碼轉為易語言的)

該樓層疑似違規已被系統折疊 隱藏此樓查看此樓MoveTo 1203,673IfColor 1203,673,"252489",2 ThenMoveTo 417, 242Delay 10072LeftDown 1LeftClick 1LeftUp 1MoveTo 982, 551Delay 7660LeftDoubleClick 1Delay 10Delay 30LeftUp 1LeftUp 1LeftUp 1MoveTo 1102, 709Del…

入門前端學習路線圖【送書】

大家好&#xff0c;我是若川。記得點上方音頻聽小姐姐配音&#xff0c;超級好聽。華章圖書又贊助了書籍送福利給大家。本次送4本書的抽獎方式是&#xff1a;截止到9月6日&#xff08;周一&#xff09;20:00&#xff0c;在留言區留言任意內容。我會在留言區抽取「1位」關注我公眾…

單選按鈕設置為被選中狀態_為什么要設置錯誤的按鈕狀態

單選按鈕設置為被選中狀態當正確的方法出錯時 (When the right way goes wrong) Let’s say you want to create a click effect on an HTML button. The first idea that many people get is to do something that reproduces the feeling of the sound emitted by a real but…

「娃娃分享」-常見自校檢分析實例.

自校檢是許多軟件的保護手段之一&#xff0c;對軟件加個簡單的殼再增加自校檢在一定程序上可以抵擋住一大部分新手&#xff0c;不過&#xff0c;對許多人來說&#xff0c;這個保護已經很弱了。。下面講幾種常見的解決自校檢方法&#xff0c;寫的粗略&#xff0c;希望大家補充。…

用VC和MinGW導出dll的def和lib(a)文件

為什么80%的碼農都做不了架構師&#xff1f;>>> 原文地址&#xff1a;http://zhangyafeikimi.iteye.com/blog/404580 有了dll文件需要導出def文件&#xff1a; pexports zlib1.dll > zlib1.def 有了dll和def文件&#xff0c;需要導出MinGW的.a文件&#xff1a;…

51中斷編程c語言,[新人求指教]51C語言編程可否用中斷令循環結束提早結束

該樓層疑似違規已被系統折疊 隱藏此樓查看此樓C51_C語言編程控制流水燈硬件電路 p0 接 led 8 個&#xff0c;P33 接按鍵使用中斷2開機燈按1~8逐位閃爍&#xff0c;并循環按鍵后改為 兩燈亮 的流水燈下面寫了個程序#include #include #define uchar unsigned char#define uint u…

產品設計美學案例分析_美學在產品設計中的重要性

產品設計美學案例分析重點 (Top highlight)In one of my previous jobs, I had really interesting debates with the CEO regarding whether we should spend more time improving the way our app looks and feels. ‘How could he not care that the design is outdated?! …

即將到來的ECMAScript 2022標準

大家好&#xff0c;我是若川。周末分享一篇相對簡單的文章。最近組織了源碼共度活動&#xff1a;1個月&#xff0c;200人&#xff0c;一起讀了4周源碼&#xff0c;參與的小伙伴都表示收獲很大。如果感興趣可以點擊鏈接掃碼加我微信 ruochuan12。另外&#xff1a;昨天的推文入門…

c語言中二叉樹中總結點,C語言二叉樹的三種遍歷方式的實現及原理

二叉樹遍歷分為三種&#xff1a;前序、中序、后序&#xff0c;其中序遍歷最為重要。為啥叫這個名字&#xff1f;是根據根節點的順序命名的。比如上圖正常的一個滿節點&#xff0c;A&#xff1a;根節點、B&#xff1a;左節點、C&#xff1a;右節點&#xff0c;前序順序是ABC(根節…

動態庫的創建與使用

1、動態庫文件的創建 &#xff08;1&#xff09;編寫源文件 &#xff08;2&#xff09;編譯生成動態庫 g -fPIC -shared -o libfile_operation.so file_operation.cpp 此編譯過程分為兩步&#xff0c;等同于下面的兩個命令&#xff1a; g -c -fPIC file_operation.cpp …

ux設計中的各種地圖_UX寫作中的移情

ux設計中的各種地圖Demetri Martin is a master of comedic situations. If you’ve never seen Demetri Martin是喜劇情境的大師。 如果你從未見過 him before, he has a sort of dry brand of observational humor, relying more on anecdotes than full stories, and often…

字符串搜索。HOJ1530 Compound Words。

stl set實現字符串搜索。。效率一般。(附二分搜索。) Compound WordsTime limit:1sec.Submitted:233Memory limit:32MAccepted:81Source: Waterloo ACM Programming Contest Sep 28, 1996 You are to find all the two-word compound words in a dictionary. A two-word compo…

字節3-1前端面試官自學Vue的正確姿勢

大家好&#xff0c;我是若川。前不久和一個字節前端TL朋友聊天&#xff0c;說到大廠前端供需脫節的情況。特別是使用Vue框架的&#xff0c;因為簡單易學好上手&#xff0c;但是能夠深入理解的人并不多&#xff0c;大多都只停留在應用層面&#xff0c;缺乏更深層面的理解。尤其是…

android視圖工具,android studio的HierarchyViewer工具如何知道android屏幕的視圖屬性

讓我們首先看看adb是如何組織的.它有3個主要組件,如here所述 –> client – 在用于開發的機器上運行的客戶端.通過發出adb命令從shell調用客戶端.層次結構查看器還會創建adb客戶端.> server – 在開發計算機上作為后臺進程運行的服務器.它將從adb客戶端發出的命令傳遞給a…

云時代架構讀后感4--IT架構的本質

IT架構的本質 原文地址&#xff1a;http://mp.weixin.qq.com/s?__bizMzAwNTQ4MTQ4NQ&mid2453562304&idx1&snbe86a7bc682c4e76e06b87a10ad45188&chksm8cd136a2bba6bfb430103e50f94b670e799412d0a1cae4eded0eb901847b6d462359ae317635&mpshare1&scene23…

蘋果風格ui_蘋果如何使Soft-UI成為未來

蘋果風格ui重點 (Top highlight)Apple announced some pretty wild updates at WWDC 2020 today.蘋果今天在WWDC 2020上宣布了一些相當瘋狂的更新。 But technology aside, let’s focus on how their UI has changed. It went through the first bitmap representations, thr…

【數據結構】量子危機

問題 宇宙時間公元 5.55 億年&#xff0c;由于某種原因兩大聯盟展開了激戰&#xff08;maxingc 聯盟采用了微子技術&#xff09;&#xff1a; 邪惡的 maxingc 聯盟采集好了微子能&#xff0c;就要運輸。Maxingc 聯盟的領袖 xc 此時才發現&#xff0c;自己的軍事基地中由微子發射…

android 自定義menu背景,Android編程實現自定義系統菜單背景的方法

本文實例講述了Android編程實現自定義系統菜單背景的方法。分享給大家供大家參考&#xff0c;具體如下&#xff1a;不多說&#xff0c;上圖&#xff0c;見代碼。package lab.sodino.menutest;import android.content.Context;import android.app.Activity;import android.os.Bu…