一個圓角被禁止移植之後:五套技術棧的 Admin,是一場被排好規則的對照實驗
從 Better Admin 用五種技術棧各寫一遍同一套後臺系統的對照實驗看起,觀察圓角、契約與骨架屏如何被設計成一致性的規則。
2026 年 9 月 24 日,掘金作者「白霧茫茫丶」發布了一篇題為《VibeCoding 一套 Admin 系統,五種技術棧實現》的長文。這個名為 Better Admin 的專案,用同一份需求、同一套資料庫、同一份接口契約,分別以 React、Vue、Next.js、Nuxt 與 NestJS 寫了五遍,外加一個文件站,共六個可獨立部署的應用,34 天全部上線。與其說這是一個開源專案,不如說它是一次被精心排好的對照實驗,而實驗的設計本身,比「哪個框架更好」的答案更值得看。
動手之前,先鎖死三條約定
後臺管理系統的需求高度同質:登入、用戶、角色、選單、字典、日誌、組織、Dashboard,誰家做的都差不多。作者正是看準這一點,把它當成理想的對照場。但多端同構專案最先崩壞的地方,往往是「同一份東西存在五個版本」,所以作者在動手前先鎖了三件事。
第一,OpenAPI 是唯一真源。契約先於實作,真源是一份 openapi.yaml 檔案,當時版本 v1.14.0,含 48 條路徑、77 個操作,五個應用的路徑、方法、響應信封、錯誤碼、分頁參數逐字一致。校驗也不靠自覺:線上跑 contract-diff,31 步逐接口比對 Next、Nuxt 與 Nest 的響應,不一致就非零退出。
第二,一個資料庫四端共用,統一 Drizzle ORM 加 17 張表,PostgreSQL 由 Supabase 託管但只當資料庫用。瀏覽器端禁止直連資料庫,連線串只存在於服務端環境變數。
第三,權限由服務端強制校驗。前端路由守衛只是體驗層,後端必須獨立再驗一次。六個線上端都是唯讀演示模式,一個註冊為全域的守衛先於路由級守衛執行,所以未登入的寫請求直接回 403,而不是先給個 401 讓人猜原因。這個細節很有介面設計感:錯誤碼的語意被想清楚了,回饋才不會誤導人。
一致性對齊的是行為,不是數值
文章裡最耐讀的一段,是關於「哪些允許不同、哪些強制一致」的切分。同一個頁面有四次實現,主色不同、圓角數值不同、圖表引擎不同,這些是允許不同的部分。強制一致的是頁面結構、API 契約、認證權限行為、i18n 鍵值,以及 DataTable 首屏 6 行骨架屏。
圓角是最好的例子。React 與 Next 端走 HeroUI 的 calc(var(—radius) * N),Vue 與 Nuxt 端走 Nuxt UI 自己的 —ui-radius,規範明確禁止移植 theme.css 或自建映射層。換句話說,圓角的具體數值被交給各框架的設計系統,但「誰有資格定義圓角」這件事被鎖死了。這其實是一套品牌規範的寫法:管住層級,放開像素。這種思路也出現在我們先前觀察過的校徽設計的視覺慣例裡,圓形先被畫好了,個別學校只能在裡面填自己的字。
刻意讓差異浮上來
另一個設計決策是讓 Next 和 Nuxt 各自帶服務端。作者的理由很清楚:如果四端都只是 Nest 的客戶端,「Next 對 Nuxt」就退化成渲染模式的比較,因為兩邊調的是同一套 API。各寫一遍服務端後,差異才真的浮出來,Next 用 httpOnly Cookie,Nuxt 用 Bearer 優先加 Cookie 回退的雙源鑑權,鑑權插在哪一層、快取語意、錯誤處理全都不一樣。
專案也不引入 monorepo 的 workspace 機制,六端獨立 lockfile、獨立構建、獨立部署,只因為放在同一個目錄就產生耦合。這種「物理隔離換乾淨對照」的做法,跟實驗設計裡控制變數的邏輯一致:連相依鎖定檔都不共享,比較結果才不容易被套件版本污染。
結語:實驗的價值在規則,不在結論
作者明說不給「誰更好」的結論。這個取捨本身是誠實的:五種技術棧各有自己的設計系統與鑑權慣例,硬排出一個名次,反而會遮掉真正的發現。Better Admin 值得看的地方,在於它示範了如何把「一致性」從一句口號拆成可執行的規則,契約有真源、資料庫單一、權限雙層、圓角各歸各家、骨架屏行數寫進規範。做設計規範的人大概都遇過同樣的難題:管太緊處處一樣,管太鬆處處走樣。這個專案給出的答案是把層級講清楚,數值留給各家的設計系統,行為寫死在契約裡。
主題 介面與互動設計
標籤 #betteradmin專案設計、#前端框架介面設計、#多端一致性規範