Svelte 給前端的一面鏡子,不是一張神主牌
Svelte 給前端的一面鏡子,不是一張神主牌
我寫這篇不是要勸你換框架。Svelte 對我比較像一面鏡子,它把幾件我一直覺得前端該守的東西,剛好同時做對了,於是你可以拿它當參考,回頭照一照自己手上那套是不是哪裡長歪了。重點從來不是品牌,是它示範出來的那些原則。我不追最大生態,但在這一票現代框架裡,Svelte 確實是相對簡潔的一個選項。
寫起來像標記加狀態
Svelte 5 的 runes 在去年十月發布,到現在算穩了。它最值得看的地方,是把響應式從「靠編譯器猜」改成你自己寫清楚。let count = $state(0),count 還是個普通數字,你照常 count++,要衍生值就 $derived,沒有 .value 包裝,也沒有 virtual DOM 那層 diff 夾在中間。編譯器幫你生出直接碰 DOM 的程式碼,你腦袋裡跑的模型,跟畫面上實際發生的事情幾乎是同一件。
這就接回我一直講的那條線:寫前端的人不該被框架糊掉對 DOM、對 HTTP、對瀏覽器的直覺。React 那套 re-render 模型逼你時時記得整個 function component 會重跑,於是有 useMemo、useCallback、依賴陣列一整組工具,那些多半不是在解業務問題,是在跟框架的執行模型角力。Svelte 把記帳收回編譯器,但記帳的規則列在你看得到的地方。少一層抽象,你離真正在發生的事就近一點,這跟先用標記描述結構、再包一層輕量行為的想法是同個方向。
當然顯式有它的代價,幾條規則要記:$state 套物件會回傳深層響應的 proxy,但 destructure 出來就斷了響應,class 欄位要各自標。這些不難,但你得知道。用「狀態怎麼流」去理解,別當 API 背,不然遲早在某個邊界踩到。
HTML 是主角,JS 來補行為
SvelteKit 的設計很一致:預設 SSR 加 client hydration,load 在 server 跟 browser 都能跑,form actions 優先於自己刻 REST,progressively enhance 到有 JS 再加互動。換句話說,沒 JS 的時候那張表單照樣能送,JS 載進來只是讓體驗更流暢。這正是「HTML 是主角、JS 補行為」的標準姿勢,不是反過來先假設瀏覽器一定有一坨 JS 在跑、伺服器只負責吐 JSON。
把 server 當第一線、client 接手互動,這個分工跟 htmx 那種 server 主導互動的精神是同源的,只是 Svelte 走得更全。+page.server.ts 處理 server-only 的事,+page.ts 處理兩側都能跑的,真要做 API 才用 endpoint。它沒有把所有東西都吸進框架抽象裡,HTML 還是那個會先到使用者眼前的東西。
不過框架的 server 層方便歸方便,邊界還是得自己守。SvelteKit 能跑 server load、能開 endpoint,但這是能力,不是叫你把對外部服務的認證、服務間的信任邊界、獨立的 rate limiting 全塞進去。面向瀏覽器的資料聚合放這層很合理,面向後端的風險邏輯該往獨立服務丟。框架能做不等於應該讓框架做,這兩個問題永遠分開問,不然六個月後沒人說得清那段 auth 到底跑在哪。
把幾條線收在一起
講到這裡,我其實是在把以前散落的幾個堅持整合成一束:別讓框架糊掉你的 DOM 直覺、讓 HTML 當主角而不是被 JS 架空、server 邊界要自己劃清楚別讓方便性替你決定。Svelte 剛好同時尊重這三件事,所以它讀起來順,不是因為它潮,是因為它沒有逼你跟這些原則對著幹。
但話說回來,Svelte 只是一個樣本。它示範了「現代框架也可以不那麼 over-engineering」這件事是做得到的,可你真正要帶走的不是 $state 怎麼寫、form actions 怎麼接,而是那幾條原則本身。哪天有別的框架同樣尊重這些,照樣值得看。鏡子的用途是照出自己哪裡歪了,不是讓你對著鏡子拜。
重點整理
- Svelte 5 runes 把響應式寫成顯式 primitive,少一層 virtual DOM,寫起來接近「標記加狀態」,離真正發生的事更近。
- SvelteKit 預設 SSR 加 form actions 漸進增強,沒 JS 也能用,是「HTML 主角、JS 補行為」的標準姿勢。
- 框架 server 層能跑邏輯是能力不是授權,面向後端的風險邏輯該往獨立服務丟,邊界自己守。
- Svelte 同時尊重 DOM 直覺、HTML-first、server 邊界三條線,所以讀起來順,順的是原則不是品牌。
- 把 Svelte 當參考實作就好,要帶走的是那幾條原則,不是對著框架拜。
觀點 Sheng,內文 Claude 協助 · 列入 20260613 blog 翻新計劃,新漆未乾。