開發紀錄
導入 copy-and-own UI 元件後,誰負責維護它
從本站的本地 Button、共用 tokens 與 CLI 設定,說明複製元件後如何管理客製差異、依賴和更新範圍,而不把上游版本當成整站行為的保證。
- 元件設計
- bejamas/ui
- 維護
- Astro
把元件原始碼放進專案後,修改圓角或預設屬性很直接。但下一次上游提供新版時,問題就變成:哪些內容可以換掉,哪些已經是這個網站自己的行為?
本站採用 bejamas/ui 的 copy-and-own 方式。CLI 提供取得元件的入口,實際被頁面引用的則是專案裡的原始碼。Bejamas 的 CLI 文件也把新增描述為寫入 alias 指定的位置,並提供 --dry-run 預覽寫入內容。[1]
我會把這類元件當成本地程式維護。上游仍是有用的參考,但更新決策要回到目前的使用點,不能只看版本號。
元件開始客製後,就有自己的契約
本站 Button 支援 as="a"、as="button" 和 as="summary",呼叫端依用途選擇元素。沒有指定 as 時,預設輸出 button;輸出 button 時先給 type="button",呼叫端仍能明確覆寫成 type="submit"。
這些選擇已經影響頁面如何使用它。作品卡片的 Demo 入口傳入 as="a" 與 href,關於頁的頭像放大則是動作按鈕。只把 Button 換成另一份「長得一樣」的檔案,還不能證明這些用途都保留了。
Button 也使用本站的色彩和動態 tokens,並保留 focus-visible 與 reduced-motion 分支。這些都是目前本地原始碼的一部分,不應被誤當成所有上游版本都提供的預設。
因此,維護時要留下的是可追查的差異:改了哪個預設、哪些使用點依賴它,以及需要怎麼確認輸出。本站的說明文件已記錄 Button 的本地 type 行為;若之後再改契約,也應同步說明,而不是只在某次對話裡提過。
CLI、元件和依賴是不同的更新對象
本站把 Bejamas CLI 放在開發依賴中,透過自己定義的 ui:add script 使用它。Button 的本地實作則引用 class-variance-authority 和 cn;cn 又使用 clsx 與 tailwind-merge。
這條關係可以簡化成:
CLI → 取得或產生原始碼
頁面 → 本地 Button → variants 與 class 合併 helper
更新 CLI 不等於更新了所有本地 Button;保留 Button 檔案,也不等於它不再依賴其他套件。這兩件事需要分開檢查。
目前 manifest 固定了 CLI 版本,lockfile 也保存解析結果。但這不能替下一次遠端取得的元件內容背書。較穩妥的做法仍是先看預計寫入內容,再審查實際差異,不因工具版本固定就略過這一步。
最初的導入紀錄回答的是如何把一個 Button 接進網站;這篇關心的是,接進來之後,誰持續照顧這些差異。
更新前,先列出不能被覆寫的部分
我會先整理一份短的本地契約,再和上游候選版本比較。以下以本站 Button 為例,是維護時的檢查方向,不是本次已執行的升級結果。
| 需要保留的責任 | 比較時要看的地方 |
|---|---|
| 導覽仍是真正的連結 | as="a"、href 和實際輸出標籤 |
| 動作不意外送出表單 | 本地 type="button" 預設及明確覆寫 |
| 呼叫端能調整樣式 | variants、class 與 cn 的合併結果 |
| 色彩維持單一來源 | 元件引用的語意 tokens 與共用樣式 |
| 鍵盤及減少動態偏好 | 焦點提示、狀態樣式與 reduced-motion 分支 |
共用元件的改動可能同時影響多個頁面,所以不能只拿示範頁比較。候選版本若改了 prop 名稱、slot 或資料屬性,還要沿著目前使用點確認:它們是否靠這些介面設定目的地、外觀或行為。
有必要的上游修正可以合進來,但不必整份覆寫。若只需要一段邏輯,保留本地契約並做窄範圍修改,通常比較容易說明這次究竟改了什麼。這是我的維護取捨,不是對所有專案更新成本的量測。
原始碼看起來獨立,樣式仍可能影響全站
本站把語意色彩映射集中在共用 CSS。Button 引用的是這些名稱,而不是在每個頁面重新寫一套色碼。這讓元件能跟著網站設計調整,也代表 token 改動的影響範圍可能大於單一 Button。
新增元件時也是如此。預期只加一份 .astro 檔案,實際變更卻可能包含 helper、依賴和全域 CSS。本站的導入規則因此要求審查 CLI 的寫入內容,不直接接受整套 base reset,也不盲目覆寫已有客製的元件。
我會把「這個元件需要的樣式」和「這次是否要改整站樣式」分開問。前者可以是必要依賴,後者仍需要獨立的理由和範圍。
如果沒有新需求或必要修正,上游多一個 variant 也不表示網站一定要跟著增加。維護不是把所有新選項都搬進來,而是讓目前使用的契約繼續成立。
檢查要跟著使用方式走
Button 的標籤、屬性與 class 合併,可以透過實際渲染的 HTML 檢查;但焦點是否清楚、觸控是否容易操作,仍要在對應介面上確認。沒有被頁面引用的 variant,整站 build 也未必會渲染到。
互動元件還有更多責任。本站的作者介紹使用 Popover,文章目錄使用 Drawer;不能拿 Button 的輸出檢查,代替它們的開關、焦點和關閉行為驗證。
一次更新的交付應說清楚:調整了哪個本地契約,檢查了哪些實際使用點,還有哪些互動或外觀尚待確認。這樣,下次維護的人才知道要接著檢查什麼,而不是只得到一句「元件已更新」。
紀錄範圍
本文依據本站目前的 Button、class 合併 helper、CLI 設定、共用 tokens 與頁面使用點整理。更新比較表是維護建議,這次沒有升級元件、重新取得 registry 內容或量測維護工時,也不宣稱現有全部互動已通過新的驗收。
copy-and-own 給了我們直接修改的空間,也把本地差異的管理留在專案裡。我的選擇是保留能說明的契約,再決定要採用哪些上游變更。