跳到主要內容

Code Review:審什麼、什麼時候擋下來

依嚴重程度分層的審查順序、每一層的具體檢查項目、一份可以貼給 AI 的自審 prompt,以及什麼情況必須退回。

約 4 分鐘 · code-review.md

0. Review 在做什麼

不是在比個人喜好,不是在挑微優化,不是在炫技。

是在確認:架構一致、資料流可預測、抽象邊界正確、六個月後還維護得動。

如果一個改動讓短期速度變快、但讓系統變難理解,它應該被退回。

1. 審查順序(照嚴重度)

由上往下。上面的沒過,下面的不用看。

1. 資安        金鑰、XSS、權限
2. 資料正確性  資料流、狀態模型、race condition
3. 架構        分層、依賴方向、責任
4. 型別        any、斷言、API 型別
5. 無障礙      鍵盤、焦點、對比、語意
6. 設計系統    token、變體、設計頁
7. 效能        不必要的重繪、包大小
8. 可讀性      命名、註解、檔案長度

2. 每一層看什麼

資安(必擋)

  • 有沒有金鑰進到會打包給前端的檔案?
  • {@html} / innerHTML 的來源是不是可信的?
  • 外部來的 URL 有沒有檢查 scheme?
  • 每個 API 端點有沒有驗證擁有權(不只是登入)?
  • 錯誤訊息有沒有洩漏堆疊、路徑、SQL?
  • 重導向參數有沒有驗證?

資料正確性(必擋)

  • 資料是不是往下流、事件往上流?
  • 有沒有同一份狀態存在兩個地方?
  • 有沒有布林爆炸?(isLoading + isError + data
  • 非法狀態是不是「無法被表達」,而不是「我們保證不會發生」?
  • 非同步操作有沒有處理競態?(快速切換兩次分頁,會不會顯示舊資料?)
  • 有沒有 module-level 可變狀態出現在會 SSR 的檔案裡?

架構

  • UI 元件有沒有 fetch?
  • 領域邏輯有沒有漏進 UI 元件?
  • 頁面有沒有商業規則?
  • 有沒有循環依賴?
  • 同一段邏輯是不是被複製了第三次?(第二次可以忍,第三次要抽)

型別

  • 有沒有 any
  • 有沒有為了消錯而用的 as
  • API 回應有沒有型別,而且在邊界驗證過
  • 複雜狀態有沒有用 union?

型別標注不等於型別安全。response.json() as User 是騙自己 —— 執行期什麼都可能回來。

無障礙

  • 鍵盤走得完嗎?
  • focus 看得見嗎?
  • 圖示按鈕有 aria-label 嗎?
  • 顏色是不是唯一的資訊管道?
  • 表單欄位有 <label> 嗎?
  • 彈窗有沒有焦點鎖定與 Escape?

設計系統

  • 有沒有寫死的顏色、字體、間距、圓角?
  • 新的變體有沒有加到設計頁?
  • 有沒有繞過設計系統做局部覆寫?
grep -rn "#[0-9a-fA-F]\{3,8\}" src/lib/modules/
grep -rnE "(margin|padding|gap): *[0-9]+px" src/lib/modules/

效能

  • useMemo / useCallback 是有量測過才加的嗎?(沒有就拿掉)
  • 有沒有在 render 裡做昂貴計算?
  • 新增的依賴有多大?(npx bundle-phobia <pkg>
  • 圖片有沒有尺寸與現代格式?

可讀性

  • 檔案能用一句話描述嗎?
  • 有沒有註解在翻譯程式碼?
  • 命名有沒有無意義的縮寫?

3. 什麼時候必須退回

  • 架構規則被違反且沒有寫明理由
  • 狀態模型不清楚
  • 繞過設計系統
  • 型別安全被犧牲
  • 有資安問題

「先合再說,之後再修」在這五項上不成立。 這五項的技術債是複利。

4. 怎麼給意見

✗ 這樣寫不好
✓ 這裡的 fetch 放在 UI 元件裡,這個元件就沒辦法在別的地方重用了。
  建議搬到 services/order.ts,元件收整理好的資料當 props。

✗ 為什麼不用 X?
✓ 有考慮過 X 嗎?它的好處是 A,代價是 B。如果你已經評估過選了現在這個做法,
  可以在註解裡寫一句理由,避免下一個人再問一次。

區分「必須改」與「可以討論」:

[必改] 這個 API key 會被打包進前端
[建議] 這個函式可以拆成兩個,但不影響正確性
[疑問] 這裡為什麼要 setTimeout 0?

5. 給 AI 的自審 prompt

請針對剛才的改動做一次 code review,照這個順序,逐項回答「有 / 沒有」,
有問題的直接修,並說明你改了什麼:

1. 資安:金鑰外洩、XSS、缺少權限檢查、錯誤訊息洩漏內部資訊
2. 資料流:狀態重複、布林爆炸、非法狀態可被表達、競態
3. 架構:UI 元件 fetch、領域邏輯漏進 UI、循環依賴、第三次複製
4. 型別:any、消錯用的 as、未驗證的 API 回應
5. 無障礙:鍵盤、focus、label、aria-label、顏色單一管道
6. 設計系統:寫死的顏色與間距、沒進設計頁的變體
7. 效能:沒量測就加的 memo、render 裡的昂貴計算
8. 可讀性:翻譯型註解、無意義縮寫、超過 250 行的元件

不確定的地方列出來問我,不要猜。

6. 通過的意思

這次改動之後,系統比之前更容易理解。

不是「沒有明顯錯誤」,是「更好懂了」。

顯示設定

這裡改的每一項,會即時套用到站上所有預覽。

風格

密度

圓角

動態

系統層級的「減少動態效果」永遠優先於這裡的設定。

語言