開發紀錄
導入 bejamas/ui:先加一個 Button,不讓元件庫接管網站
從一個原生 Astro Button 開始,記錄按需導入 UI 元件時如何審查 CLI、樣式、依賴與 HTML 語意,保留原有設計與修改邊界。
- Astro
- bejamas/ui
- Tailwind CSS
- 元件設計
這個作品集網站剛改成原生 Astro,頁面已經有自己的灰藍、亮藍配色和按鈕樣式。我們想加入共用 UI 元件,讓後面的頁面少寫一些重複的介面程式,但沒有打算在安裝元件時一起更換整站設計。
這次我們把導入限制在一個 Button。先確認元件怎麼落進專案、能不能用既有色彩、輸出的 HTML 是否符合用途,再決定要不要往下加。
我先想看清楚,一個元件會改到多少地方。如果連全站背景、字色和原本的控制都跟著變,後面就很難分辨是哪一步造成的。
先看元件怎麼加入專案
我們選用的 bejamas/ui 是面向 Astro 與 Tailwind CSS v4 的元件系統,官方提供透過 CLI 按需加入元件的流程。[4]
Button 的原始碼會放進我們的專案,之後可以直接修改,這種方式常稱為 copy-and-own。我們也就要負責理解和維護它;原始碼在手上,並不表示更新時可以不用檢查。
我先確認元件會存在哪裡、需要哪些輔助函式和套件,以及它會如何改動全站 CSS。示範站上的 Dialog、Tabs 等控制,等頁面真的需要時再加。
一個原生按鈕也不能代表整套互動元件都已經驗證。後面真的需要 dialog 或 drawer 時,鍵盤、焦點與新增的瀏覽器腳本,仍要另外檢查。
先 dry-run,不先改整站設定
我們先核對當時 CLI(命令列工具)的說明,採用固定版本的 bejamas 0.4.1,再把新增入口寫進 package.json。下面只摘錄和這個命令有關的設定,不是完整的安裝檔:
{
"scripts": {
"ui:add": "bejamas add"
}
}
有了這個設定和已安裝的 CLI,才能在本專案執行下面的預覽命令:
npm run ui:add -- button --dry-run
--dry-run 用來看預計寫入的內容。[5] ui:add 是我們自己定義的 script 名稱,並非 npm 或 Astro 內建命令;其他專案要先完成自己的設定,安裝方式可以參考文末官方文件。
正式新增後,還要逐項看實際變更。這次除了 Button,也加入了處理 class 合併的輔助函式、樣式 import 與依賴。只點名一個元件,仍可能改到好幾個檔案。
CLI 固定版本也不是略過審查的理由。我們保留的規則是:每次 add 都看它實際產生了什麼,不盲目執行整套 init 或 apply,更不覆寫已經客製過的元件。
色彩留在原本的來源
這次新增 Button 時,原本的灰藍與亮藍色系保持不變。後續要換配色,可以另做一輪調整,不跟元件導入混在一起。
元件使用 background、foreground、border、ring 等名稱,分別代表背景、文字、邊線和焦點提示。我們把這些語意色彩接到原本的色票。下面是實際樣式中的一小段:
@theme {
--color-siteBg: #e0e6ec;
--color-black: #1c1e19;
--color-primary: #273cf7;
}
@theme inline {
--color-background: var(--color-siteBg);
--color-foreground: var(--color-black);
--color-ring: var(--color-primary);
}
@theme 保留原站色票;@theme inline 再把元件需要的名稱接到這些顏色。這些共用設定就是設計 tokens,集中管理後,頁面不必各寫一組色碼。
這次也保留了原有 Font Awesome 圖示系統,沒有因為元件範例用了另一套圖示,就替換整站。
樣式審查也看了 CLI 加入的全域 base 規則。這類 CSS 會影響按鈕以外的元素,我們沒有全部留下。尤其用鍵盤 Tab 移動時,原站的 focus-visible 焦點提示要繼續看得見。
這裡的取捨很務實:先讓元件適應網站,之後真正改版時,再集中調整設計 tokens。
看起來像按鈕,也要輸出正確的元素
外觀可以一樣,用途卻要分清楚。前往其他頁面的是連結,輸出 <a> 與真實的 href;觸發操作才用 <button>。下面是最小的用途示意,省略樣式與操作腳本:
<a href="/about">關於這個網站</a>
<button type="button">開啟選單</button>
<button type="submit">送出表單</button>
這次加入的 Button 元件支援 as="a",讓第一種用途仍輸出真正的連結。讀者可以用瀏覽器原本的方式開新分頁,不需要把所有導覽都改成 JavaScript 點擊事件。
我們也把動作按鈕預設為 type="button",需要送出表單時再明確傳 type="submit"。這是本專案的本地修改,不把它寫成所有版本的元件庫預設。
這些差異用眼睛看不一定明顯,所以驗證不能只有「按鈕顏色出來了」。還要讀實際 HTML,確認 tag、屬性和 class 合併結果。
沒有使用點的元件,要另外測
基礎導入時,Button 還沒有替換既有頁面的控制,所以原站建置成功,仍不足以證明新元件真的被渲染過。
我們另外做了一個只供測試的頁面,引用同一份 Button 和 CSS,把不同尺寸、樣式和連結用途真正渲染出來。再檢查生成的 HTML:連結有沒有 href、動作按鈕的 type 是否正確、停用狀態和 class 合併是否符合預期,以及有沒有額外的瀏覽器腳本。
這份紀錄證明的是 Button 在那次測試範圍內可用,不是所有互動元件、手機排版或新版網站都已經驗收。
導入過程還碰到 Windows 原生模組檔案被鎖住,當時 npm ci 沒有成功,後來用 npm install 恢復依賴,再完成檢查。這是那次處理的紀錄,不能把 npm install 當成所有安裝錯誤的通用解法,也不能因此宣稱從 lockfile 重新安裝已經驗證過。
如果只留下一句「全部成功」,下次換環境的人就無法知道哪些條件其實還沒確認。
下一個元件,仍從需求開始
這次先做 Button,讓我們看清楚了元件來源、token 連接、CLI 寫入邊界和本地修改。
後面要加 Card 或 Badge,可以沿用這套審查方式;要加更複雜的互動控制,則增加對應的行為驗證。沒有必要為了使用一套元件庫,就把每個 HTML 元素都抽成元件。
我希望共用元件減少的是重複實作,不是減少我們對輸出與行為的理解。網站的資訊架構、內容和視覺取捨,仍然要由實際需求決定。
紀錄範圍
這篇記錄的是只加入基礎 Button 的那個階段,當時既有頁面還沒有全面換用新元件。命令設定與 CSS 節錄來自當次實作;HTML 區塊是解釋用途的最小示意。其他互動元件與後續整站改版,不在這次驗證範圍內。
Sources
[4] https://ui.bejamas.com/docs/installation [5] https://ui.bejamas.com/docs/cli