能 build 不等於設計合理:JS 工具鏈的厭世日記

某天下午我在幫一個舊專案升 Vite,打開設定檔,赫然發現它比整個業務邏輯還長。插件 10 幾個,alias 一堆,有幾行我連自己為什麼加的都忘了。build 跑得起來,lint 沒報錯,CI 是綠的。所有人都說沒問題。但那個設定檔根本就是在累積沒人敢刪的歷史包袱,只是恰好跑得通而已。

這大概是 JS 生態最典型的困境:工具鏈複雜到某個程度之後,「跑得起來」就變成了唯一的評量標準,沒有人再去問「這樣設計對嗎」。一個 React 專案五六個 Babel plugin、TypeScript 嚴格模式加上無數 override、ESLint config 繼承三層,每加一個就讓你覺得更安全、更完整、更專業,直到你意識到光是讓這些工具互不打架就消耗掉你一半的精神。build 能過,但你已經不確定那個 build 背後到底發生了什麼。

更有趣的是出問題之後的反應。程式跑錯,先罵 bundler;型別推導歪掉,先罵 TypeScript compiler;SSR hydration 爆掉,先罵 Next.js。很少有人停下來問:是我對資料流的假設錯了,還是我選錯了抽象層?工具崇拜的副作用就是這個,把問題的責任推給生態,然後用「換個工具」代替「重新思考設計」。換 Vite 換 Turbopack 換 Bun,換完之後複雜度還是在,只是暫時藏在新工具的蜜月期裡。

我不是說工具不重要,Vite 比 Webpack 快這件事是真的,Bun 的啟動時間也確實讓人驚喜。但工具解決的是工具層的問題,它沒辦法幫你把一個職責混亂的 component 變得清晰,也沒辦法讓一個被 overfit 的 API 設計變合理。能 build 只是在說你的工具鏈設定沒有互相衝突,跟你的設計有沒有道理是兩件完全不同的事。

node_modules 裡有 1200 個套件這件事我已經接受了,但我沒辦法接受的是,大家把這當作理所當然,而不是當作一個值得懷疑的訊號。

重點整理

  • 「能 build」只證明工具鏈設定沒互相衝突,跟設計是否合理無關。
  • 設定檔比業務邏輯長,是一個應該停下來想一下的警訊。
  • 出問題先檢討假設與設計,再去怪工具或生態。
  • 換工具帶來的快感通常只是把複雜度搬個位置,根本問題還在。
  • 工具解決工具層的問題;資料流、職責劃分、邊界設計,那是你的責任。

觀點 Sheng,內文 Claude 協助 · 列入 20260613 blog 翻新計劃,新漆未乾。