EP5 - 作為一個前端工程師,我是怎麼debug的
這集講講工程師的必備技能之一
debugging
這也不局限於前端工程師 只要是工程師在任何職涯階段一定都會碰到有bug需要debug的時候
不一定是你寫的可能是別人寫的code需要debug
我覺得這個機會是增長自己能力最快的方法而且也會慢慢累積一套自己的best practices和anti-pattern
會記得之前這樣寫產生了什麼樣的問題所以下次要注意
我之前遇到過一個bug是不曉得為什麼使用者沒法等入了
後來發現是我們GraphQL那邊中間因為要有logging的需求但不想直接顯示使用者打的密碼所以會變成星號
但不小心的是因為JavaScript object是pass by reference的 我們直接改了那個object
導致某些操作下使用者的密碼真的變成星號了
是一個寶貴的經驗哈哈
我覺得debug的第一步要先承認你所覺得的這段code應該怎麼操作的可能是不對的
要是對的它就不會這樣了
情緒要先放下來 看過很多人對著電腦喃喃自語說why doesn't it work???
bug不是我們說一說它自己就會好了
如果可以的話請教教我
alright 假設今天有使用者回報說這個頁面有bug 我們先試著reproduce試試按照使用者說的什麼先點了這個畫面 打了什麼字 按了什麼的button結果應該跳出個modal但沒有
根據bug的輕重緩急我們不一定會馬上修, bug ticket如果是我們工程師開那記得一定要把reproduce steps寫上去好讓下一個拿到這ticket的人可以試著修看看
不要一張ticket說 使用者說這個modal沒有跳出來
萬一是個剛進來的新人對business還不了解 拿到這個ticket他會有很多問號
有時候使用者不會特別跟我們說有bug除非你在大公司上班然後instagram上不去 或是 AWS server is down 那你馬上在新聞上面看到然後twitter上面刷一排為何上不去 then you know you are messed up
台灣我不是很清楚但北美這邊都會在application裡面 不管是前端還是後端 都會放比如Sentry 或是 DataDog這類monitoring tool 會把application報的錯全部放到平台上而我們工程師可以隨時查看 你也可以設定說某個error在過去一分鐘內發生3次就自動發到Slack上因為代表這類error很重要
不管使用者有沒有和你說 我們都得看懂stack trace
stack trace通常是一個error object帶上的很多相關訊息比如這個error怎麼被throw出來的 被誰throw出來的 在哪一行被throw 我們常常會這個function call那個function又call另一個function stack trace會把這些過去的路徑全部顯示出來 尤其前端我們會有build bundle 如果有source map這些monitoring platform會自動幫你把error link回source code 而不是這個a和b報錯 誰知道a跟b是什麼東西
剛剛提到的source map它的定義是a file that maps the transformed source to the original source
webpack和vite都能選擇性的build時候產生出這個檔案
我們build的時候這些code通常都是minified的 變成人很難看得懂東西
有了這個檔案這些工具和browser就能自動串起來把我們build好的code和原始碼串起來讓你在不deploy source code情況下還可以看到source code
通常建議不要在production把source map deploy出去畢竟這樣大家都能看到原始碼
第二個這個聽起來好像理所當然但情急之下加上網站有時候長得一樣自己會沒有發現
別在production上debug然後確定東西沒有被cache
在reproduce過程中可能需要update什麼data或是比如是個e-commerce你需要真的走過checkout flow
記得在dev environment做這些事
有些bug但其實不是bug是說這東西怎麼沒有跑出來 可能只是目前cache的是舊的東西 等cache invalidate之後就好了 我們也就不用再花時間看了
第三點是善用與熟悉devtool 瀏覽器在使用者手上只是個用來上網的工具各個瀏覽器中有很多好用的開發者工具
最基本的可以看到console有跳出什麼錯誤訊息
network看這個網頁從server拿到什麼資料
local storage 可以看這個app存了什麼data
給個example 假設這個頁面我們應該看到某種資料但畫面顯示說no data found
最初步的判斷可以先從network查那個有沒有這個request 或 response是不是有資料回來
如果沒有request或是response有資料結果畫面沒東西那大概就是前端有問題 如果response回來本來就沒有資料然後也是照著API doc發request的那就要請後端同事一起debug了
第四點 善用console 相關的method
大家最常用的大概就是console.log 在你的console print出任何data或string
最簡單的例子比如你要測你這個function有拿到你覺得應該有的資料
就直接用console.log來看拿到了什麼資料
或是在一連串的function裡面想知道這些function有沒有被call
用console.log來測試會不會print
console.time可以讓你簡單的測試function花多久時間跑完
第五點是可以用breakpoint和step over function
你可以在devtool裡面 以chrome為例有個sources tab 在code的某一行打上breakpoint
當browser跑到那一行時候 根據設定的condition browser會停在那邊
如果預期會停在這邊結果怎麼跑都沒有那maybe哪裡的condition設定錯了
多加一點breakpoint或是console log看看
那如果停住了 可以看看code跑到這邊 其他的variable裡面的value是什麼
幫助判斷code跑到這邊 該拿資料有沒有拿到
devtool也會給stack trace告訴你是誰叫了這一個function然後誰叫了那一個
整個history都會被列出來
然後你可以控制browser跑下一行或是跳出這個function
這可以讓你更準確的知道瀏覽器是怎麼執行你的code他的順序如何
這個如果是在local弄或是有source map的狀況下弄會比較簡單
要不然你會看這minified code猜為什麼這個f要叫這個h 這兩個是什麼鬼
第六點算life hack吧
就先去做別的事情 休息一下
應該蠻多人是在洗澡時候或睡一覺醒來後把一個bug解決了
只能說腦袋是個很神奇的東西
第七點 試著讀別人的code 尤其是library的code
今天你覺得 你篤定 是某個library有bug所以有一些奇怪的behavior
你不妨試試用前面的方法 或是node_modules 裡面打console.log 或是去他們的github抓source code下來讀
說不定還能順便發個PR直接修bug 在resume上面寫對open source用貢獻
第八點我發現蠻多人用但很少人有寫出來
大概概念是用binary search
不是要你寫出來
是當你完全不曉得為何目前這個bug會是這個樣子
你就開始刪code
但一個一個刪太慢了 你就一次刪一半
如果bug還在 再刪剩下一半
如果發現bug沒了
把刪掉的一半加回一半
那如果整個檔案都刪掉了bug還在
那就是不在這個檔案裡
找下一個開刀
這雖然不是特別的scientific但很有效
當初Vue 3剛出來時候我們的SSR要migrate到Vue 3
當時有一個bug是在某一個點Vue會沒辦法繼續render然後server crash
就是用這個方法找到哪一行然後回報給Vue team的
如果你喜歡這內容的話幫我在 Twitter 和 Threads 上面分享給其他正在前端這條路上努力的朋友們,也別忘了訂閱我們電子報收到第一手消息喔 🚀