ADR-0004:走 shadcn registry,不發 npm 元件套件
- 狀態:已採用
- 日期:2026-07
背景
元件庫的散佈方式有兩種主流:
- npm 套件:
npm install @dooping/react,import 使用 - registry / 複製原始碼:把元件原始碼複製進使用者的專案
選項
| 選項 | 優點 | 缺點 |
|---|---|---|
| A. npm 套件 | 升級簡單、版本可控、bundle 可最佳化 | 客製化只能靠 props 與 CSS 覆蓋;需求一特殊就 fork |
| B. registry 複製 | 複製後完全可改;無升級壓力 | 沒有自動升級;重複程式碼 |
| C. 兩者都提供 | 全都要 | 兩套要維護,而且會分裂社群用法 |
決定
採 B:只提供 registry。
同時保留 @dooping/react workspace 套件作為開發與文件站的來源,
但不發佈到 npm;它的存在是為了 Storybook、文件站活範例與守衛測試。
理由
- 元件一定會被改。 後台系統的表格永遠有「這個 case 比較特殊」的需求。 npm 套件遇到這種需求只有兩條路:加第 15 個 prop,或 fork。兩條都不好。
- 升級壓力是負債。 元件套件的 major 升級意味著全站回歸測試。 複製走的程式碼沒有這個問題——它就是你的程式碼。
- 真正該統一的是 token,不是元件實作。 只要 token 一致, 兩個團隊各自改過的 DataTable 看起來仍然是同一家的產品。
選項 C 被否決:兩種散佈方式並存,會出現「A 團隊裝套件、B 團隊複製原始碼」, 然後 bug 修在其中一邊。
影響
- 使用者複製走之後,上游修 bug 不會自動傳播。 緩解:CHANGELOG 要寫清楚「這個修正影響哪個檔案」,讓人能手動同步。
- registry JSON 需要改寫 import 路徑(相對路徑 →
@/別名),由建置腳本處理。 registryDependencies用完整 URL,讓相依可以自動一起裝。- 元件版號的意義從「你該升到哪一版」變成「你抄的是哪一版」。