跳到主要內容
實戰紀錄7 分鐘閱讀

既有系統除錯思路:從重現問題到建立防護

面對非本人撰寫的舊程式碼時,如何透過清晰的最小重現範例、斷點排查與元件解耦逐步解決問題。

接手既有系統時,最大的困難往往不是技術,而是「不確定改這裡會影響哪裡」。比起憑感覺修改,用固定的流程除錯更穩定:重現、定位、歸因、修復、防範,每一步都留下可以驗證的證據。

一、重現:先讓問題穩定發生

無法穩定重現的問題,修好了也無法證明修好。先把條件寫清楚:

  • 哪個頁面、什麼操作順序、什麼資料。
  • 只發生在特定瀏覽器、螢幕尺寸或登入身分嗎?
  • 能不能縮小到最小重現範例(Minimal Reproduction):拿掉不相關的程式碼,問題還在,代表範圍縮對了。

二、定位:用二分法縮小範圍

用 DevTools 把範圍切半,再切半:

  • Console:先看有沒有錯誤或警告,它們常直接指出方向。
  • Network:確認請求有沒有送出、狀態碼、回傳資料是否符合預期。
  • Elements:看實際套用的 CSS,以及被劃掉的規則是被誰覆蓋。
  • Sources:在可疑位置設中斷點,或用「Event Listener Breakpoints」在特定事件發生時暫停。

三、歸因:用假設驗證,不要憑猜測

介面行為問題常見的原因,可以對照著檢查:

現象常見原因驗證方式
彈窗點外面會立刻關閉,或關不掉事件冒泡或捕獲順序,點擊被上層攔截在 capture 階段記錄事件路徑
元件值沒有更新響應性失效(解構、非響應式物件)在 DevTools 檢查該值是否仍是響應式
樣式改了沒效果選擇器優先權較低,或被框架樣式覆蓋在 Elements 面板看被劃掉的規則
浮層被遮住stacking context 讓 z-index 失效檢查祖先元素是否有 transform、opacity 等
偶發錯誤非同步時序或請求競態加上時間戳記記錄,比對順序

例如要確認是哪一層攔截了點擊,可以在 capture 階段觀察事件路徑:

js
document.addEventListener('click', (e) => {
  console.log('capture:', e.target, e.composedPath())
}, true)

四、修復:最小範圍,並評估影響面

修改前先回答三個問題:

  1. 這段程式碼還有哪些地方會用到?(全域搜尋、查看引用)
  2. 修改會改變哪些既有行為?
  3. 有沒有更小的改法?例如修元件本身,而不是在每個呼叫端各補一次。

既有系統通常沒有完整測試,修復後要手動走過「會受影響的流程」,而不只是驗證被回報的那一個情境。

五、防範:讓同樣的問題不再發生

  • 補一個能重現原問題的測試;沒有測試環境時,至少把重現步驟寫進 PR 說明。
  • 能用工具擋下的,就收斂成規則,例如 ESLint 規則或元件的 props 限制。
  • 把根因記錄在程式碼註解或文件中,寫的是「為什麼這樣做」,而不是「做了什麼」。

小結

除錯的重點是把「感覺」換成「證據」:能穩定重現、能說明原因、能驗證修復、能防止再發。流程固定下來,面對不熟悉的舊程式碼時也能一步一步縮小範圍,而不是到處試改。