Glossary
ศัพท์ของ Svelte 5 เน้นที่ rune เป็นหลัก — $state, $derived และ $effect เข้ามาแทนที่ export let, $: และ <slot> — บวกกับ async Svelte (await ใส่ตรง ๆ ใน $derived และใน template ได้ ต้องเปิดผ่าน experimental.async) และฝั่ง SvelteKit ก็มีทั้ง routing, hooks และ remote functions ต่อยอดเข้ามาอีกชั้น เวลาอ่านบทเรียนแล้วเจอคำที่ไม่คุ้น หรือไม่แน่ใจว่ายังใช้ได้อยู่กับ Svelte 5.57 / SvelteKit 2.70 ไหม ให้กลับมาดูที่นี่
| Term | ความหมาย | บทเรียน |
|---|---|---|
action / use: | directive แบบเก่า: function ที่รับ DOM node ของ element (พร้อม param ทางเลือก) ตอน mount แล้วอาจคืน { update?, destroy? } เอกสารของ Svelte เองตอนนี้แนะนำให้ใช้ attachment กับโค้ดใหม่แล้ว แต่ use: ก็ยังใช้ได้อยู่ และยังเป็นสิ่งที่ library แบบ pre-attachment หลายตัวส่งมาให้เราตรง ๆ | Actions |
| adapter | plugin (@sveltejs/adapter-node, -static, -cloudflare, -auto, …) ที่บอก vite build ว่าจะแพ็ก SvelteKit app ให้เข้ากับ target ที่จะ deploy ยังไง — Node server แบบ standalone, static site ที่ prerender ล้วน หรือ format แบบ edge/worker เฉพาะ platform | Server & API |
animate:flip | directive จาก svelte/animate ที่เลื่อน item ของ {#each} แบบ keyed ไปตำแหน่งใหม่อย่างนุ่มนวลเมื่อ list เรียงลำดับใหม่ — transition อย่างเดียวครอบคลุมแค่ add/remove เพราะ keyed reorder ใช้ DOM node เดิมซ้ำ ไม่มี intro/outro เกิดขึ้นเลย | Transitions & Animations |
$app/navigation | module ที่ใช้ได้เฉพาะฝั่ง client export goto() สำหรับ navigate แบบสั่งเอง, invalidate()/invalidateAll() เพื่อบังคับให้ load รันใหม่ และ lifecycle hook beforeNavigate/afterNavigate รอบ ๆ การเปลี่ยน route | Server & API |
$app/state vs $app/stores | $app/state เปิด page, navigating และ updated เป็น runed object ธรรมดาให้อ่านตรง ๆ (page.data); $app/stores เปิดข้อมูลชุดเดียวกันเป็น Svelte store ที่ต้องมี $ นำหน้า ตอนนี้ deprecate แล้วเพื่อให้ใช้แบบแรกแทน | Loading Data |
async Svelte / experimental.async | ชุดฟีเจอร์ที่ให้ใส่ await ตรง ๆ ใน $derived และใน template ของ component ได้เลย ไม่ใช่แค่ใน <script> ระดับบนสุด ต้องเปิดผ่าน compiler option experimental.async: true ไม่งั้น Svelte จะขึ้น error จริง ๆ ทันทีที่เจอ await ในตำแหน่งเหล่านั้น | Async Svelte |
attachment / {@attach} | function ที่ใส่ผ่าน {@attach fn} รันตอน element ของมัน mount และคืน cleanup function ที่รันตอน unmount ได้ เปิดตัวใน Svelte 5.29 เป็นตัวสืบทอดที่ยืดหยุ่นกว่าของ use: action — ใช้กับ component ได้ด้วย ซึ่ง use: ทำไม่ได้ | Actions |
| Term | ความหมาย | บทเรียน |
|---|---|---|
| batching / microtask | Svelte รวม DOM update เป็น batch: effect (รวมถึงตัวที่อยู่เบื้องหลัง onMount) รันบน microtask หลังจาก mount()/hydrate() คืนค่ากลับมาแล้ว ไม่ใช่แบบ synchronous — นี่แหละคือเหตุผลที่อ่านค่าที่เพิ่งเปลี่ยนทันทีหลังจากนั้นอาจยังเห็นค่าเก่าอยู่ จนกว่า flushSync() หรือ microtask ถัดไปจะตามให้ทัน | Lifecycle |
$bindable | rune ที่ component ต้องใส่ให้ prop ที่ destructure ออกมา (let { value = $bindable() } = $props()) ก่อนที่ parent จะ bind: เข้ามาได้ ถ้าไม่ใส่ การ bind: เข้า prop นั้นจะเป็น compile error จริง ๆ ที่ถูกจับได้ ไม่ใช่แค่เงียบ ๆ ไม่ทำอะไร | Props & $bindable |
bind: / function bindings / bind:this / bind:group | bind: คือ syntax sugar ของค่า + event ที่เปลี่ยนมัน (bind:value, bind:checked, bind:files); bind:group ผูก radio/checkbox ทั้งกลุ่มเข้ากับตัวแปรเดียว; bind:this เก็บ DOM node หรือ instance ของ component หลังจาก mount แล้ว; และตั้งแต่ Svelte 5.9 binding ก็รับคู่ function {get, set} แทน identifier ธรรมดาได้ เพื่อ validate หรือแปลงค่าตอนที่มันไหลเข้ามา | Bindings |
| children | snippet prop เริ่มต้น: markup อะไรก็ตามที่ parent วางซ้อนไว้ข้างในแท็กของ component จะมาถึงในรูป prop children render ด้วย {@render children?.()} — ตัวแทนแบบมี type และรับ parameter ได้ของ Svelte 5 สำหรับ <slot> แบบไม่ตั้งชื่อรุ่นเก่า | Passing UI & Children |
class={{...}} / style: | ตั้งแต่ Svelte 5.16 attribute class ธรรมดารับ object หรือ array ได้เลย (class={{ active: isActive }}, class={[a, b && 'c']}) ประมวลผลด้วย algorithm เดียวกับ helper ยอดนิยม clsx ที่ built-in อยู่ในตัว compiler ไม่ต้องลง dependency เพิ่ม; style:prop={value} ตั้งค่า CSS property เดียวแบบ reactive โดยไม่แตะส่วนอื่นของ style | Events & Attributes |
| compiler / runes mode / legacy mode | compiler ของ Svelte เป็น static analyzer ที่ตัดสินทีละไฟล์ว่าไฟล์นั้นอยู่ใน runes mode (มี rune ตัวใดก็ได้ หรือ runes: true) หรือ legacy mode — ทั้งสองเป็นเส้นทางโค้ดคนละสาย ดังนั้นการผสม reactivity primitive ข้ามสองโหมด (export let กับ $state, $: กับ $derived) จึงเป็น compile error จริง ๆ ไม่ใช่แค่ warning | Why Svelte, the Compiler |
context (setContext/getContext) | setContext(key, value) ให้ ancestor ส่งค่าไปถึง descendant ทุกตัวได้โดยไม่ต้องส่งผ่าน prop ทีละชั้น (หลีกเลี่ยง prop drilling); getContext(key) อ่านค่าจาก ancestor ที่ใกล้ที่สุด setContext รันแค่ครั้งเดียวตอน init ดังนั้นค่าที่ส่งเข้าไปต้องเป็น runed object (อย่าง $state) อยู่แล้ว descendant ถึงจะเห็น update ทีหลังได้ | The Context API |
createAttachmentKey | สร้าง symbol key ที่ไม่ซ้ำกัน จาก svelte/attachments ใช้ทำเครื่องหมายว่า property ของ object นี้เป็น attachment เมื่อ spread object นั้นลงบน element ({...stuff}) — เป็นทางเลือกแบบ programmatic แทนการเขียน {@attach fn} ตรง ๆ เหมาะกับตอนสร้าง attachment หลายตัวจาก loop หรือรวมจากหลายแหล่ง | Actions |
createEventDispatcher (legacy) | วิธีของ Svelte 4 ในการยิง custom event (dispatch('change', detail)) ให้ parent ดักด้วย on:change มันยังคอมไพล์ผ่านโดยไม่มี warning เลยแม้อยู่ใน runes mode แต่ callback prop (onchange?.(detail)) คือตัวแทนที่ถูกต้องแบบ Svelte 5 | Events & Attributes |
createSubscriber | primitive ระดับล่างจาก svelte/reactivity ที่ reactive wrapper แบบ built-in ทุกตัว (MediaQuery, ค่าจาก svelte/reactivity/window) ถูกสร้างขึ้นบนมัน: ส่ง callback ที่ subscribe แหล่งข้อมูลภายนอกแบบ push แล้วเรียก update() ให้มัน มันจะเชื่อม notification จากแหล่งนั้นเข้ากับ dependency tracking ของ Svelte เองผ่าน getter ธรรมดา | Built-in Stores |
| CSP (Content-Security-Policy) | config kit.csp ของ SvelteKit (ใช้แบบแบน ๆ ใน config ของ plugin sveltekit() สำหรับ Vite ก็ได้) สร้าง nonce header จริง ๆ ต่อ request ให้อัตโนมัติ ทำให้ inline script/style ที่ framework ต้องใช้ผ่าน Content-Security-Policy แบบเข้มงวดได้โดยไม่ต้องจัดการ nonce เอง | Server & API |
| custom element | Web Component แบบ native ที่ Svelte compile component ให้กลายเป็นได้ผ่าน <svelte:options customElement="tag-name"> ผู้ใช้ใน framework ไหนก็ได้ (หรือไม่ใช้ framework เลย) เรียกใช้มันเหมือน DOM element ทั่วไป และ $host() คือวิธีที่ component เข้าถึง element ที่ host ตัวมันจากข้างใน | Advanced Runes |
| Term | ความหมาย | บทเรียน |
|---|---|---|
| deep reactivity / proxy | $state บน object หรือ array จะห่อค่านั้นด้วย Proxy ทำให้การเขียน property ธรรมดาและการ mutate array (arr.push(x), obj.prop = y) ถูก track อัตโนมัติในทุกระดับความลึกของโครงสร้าง — ไม่ต้องมี “setter” แยกต่างหากเหมือน store ธรรมดา | The $state Rune |
| dependency tracking | compiler ตัดสินแบบ static ว่าการอ่านค่าไหนใน $derived/$effect นับเป็น dependency — การวิเคราะห์นี้ทำก่อนที่โค้ดของเราจะรันด้วยซ้ำ และเป็นสิ่งที่ทำให้ Svelte สร้าง update แบบละเอียด (fine-grained) แทนที่จะ re-render ทั้ง component | Why Svelte, the Compiler |
depends() / invalidate() | depends(key) ข้างใน load function ลงทะเบียน dependency string แบบกำหนดเอง แล้วเรียก invalidate(key) (หรือ invalidateAll()) จากที่ไหนก็ได้ทีหลัง จะบังคับให้ทุก load ที่ประกาศ dependency นั้นรันใหม่ — วิธี trigger การ refetch เองนอกเหนือจากการรันใหม่อัตโนมัติตาม URL/param | Loading Data |
$derived | ประกาศค่าที่คำนวณจาก reactive state อื่น (let double = $derived(count * 2)) ต่างจาก $effect ตรงที่การคำนวณใหม่ของมันเป็นแบบ push-pull และ lazy — dependency เปลี่ยนแค่ทำเครื่องหมายว่ามัน dirty เท่านั้น ตัว function จะรันจริงตอนที่มีอะไรมาอ่านมันครั้งถัดไป ไม่ใช่ตามตารางของตัวเอง | The $derived Rune |
$derived.by | รูปแบบ function ของ $derived สำหรับการคำนวณที่ต้องมากกว่าหนึ่ง expression — loop, ตัวแปรชั่วคราว, การแตกเงื่อนไข $derived(expr) ก็แค่ตัวย่อของ $derived.by(() => expr) ที่มี dependency tracking และความ lazy เหมือนกันทุกประการ | The $derived Rune |
$effect | ลงทะเบียน side effect ที่รันหลัง DOM update เสร็จ รันใหม่ทุกครั้งที่ค่าที่มันอ่านตอนรันล่าสุดเปลี่ยนไป cleanup function ที่มันคืนกลับมาจะรันก่อนรันรอบถัดไปและตอน unmount ถ้าเป้าหมายจริง ๆ คือแค่คำนวณค่า ให้ใช้ $derived แทน | The $effect Rune |
$effect.pending | รายงานจำนวน async update ที่กำลังค้างอยู่ข้างใน <svelte:boundary> ที่ใกล้ที่สุด — โดยเฉพาะกรณีที่ snippet pending ของ boundary เองไม่ครอบคลุม: async update รอบถัดไป หลังจาก render รอบแรกของ boundary resolve ไปแล้ว | Async Svelte |
$effect.pre | คู่ของ $effect ที่รัน ก่อน DOM update แทนที่จะรันหลัง — สำหรับอ่าน layout (เช่น scroll position) ที่ update ที่กำลังจะเกิดขึ้นจะไปเปลี่ยนมัน มีกติกา dependency-tracking และ cleanup เหมือนกับ $effect ทุกอย่าง | The $effect Rune |
$effect.root | สร้าง effect scope ที่ ไม่ ถูกเลิกให้อัตโนมัติโดย parent — มันคืน function destroy กลับมาให้เราต้องเรียกเอง เป็นทางออกสำหรับ effect ที่สร้างนอก lifecycle ปกติของ component (state library, test, โค้ดที่ integrate แบบ imperative) | Advanced Runes |
$effect.tracking | คืน true เมื่อโค้ดที่กำลังรันอยู่ตอนนี้อยู่ใน tracking context — effect, derived หรือ template — และคืน false นอกจากนั้น มีประโยชน์เวลาสร้าง reactive abstraction เองที่ต้องรู้ว่าตอนนี้ถูกอ่านแบบ reactive อยู่หรือเปล่า | Advanced Runes |
$env/static vs $env/dynamic | `$env/static/private | publicฝัง environment variable เป็นค่า literal ตอน **build time**;$env/dynamic/private |
+error.svelte | หน้า error เฉพาะของแต่ละ folder render เมื่อ load (หรือ page/layout เอง) throw ใน subtree นั้น SvelteKit จะไล่ขึ้นไปข้างบนใน route tree จากจุดที่ error เกิด เพื่อหาไฟล์ที่ใกล้ที่สุด ถ้าไม่มี ancestor ไหนใกล้กว่า ก็จะตกไปถึง +error.svelte ที่ root | Routing & Pages |
| event delegation | Svelte ไม่ได้ผูก native listener ให้ทุก element ที่มี onclick — มันลงทะเบียน listener ตัวเดียวที่ root ของแอปแล้วส่งต่อไปยัง handler ที่ถูกต้องจากตรงนั้น เพื่อลด memory footprint ผลที่ตามมาคือ addEventListener ธรรมดาระหว่าง root กับ element ของเราที่เรียก stopPropagation() บน native event จะทำให้ handler ของ Svelte ไม่ทำงานเลยแบบเงียบ ๆ | Events & Attributes |
event.locals | object ต่อ request ที่ hook อย่าง handle เติมค่าให้ (event.locals.user = ...) เพื่อให้ load function, action และ handler ใน +server.js ที่อยู่ถัดไปอ่านได้ การ type ให้มันต้องผ่าน interface App.Locals ใน src/app.d.ts ไม่งั้นทุกจุดที่อ่านจะเป็น any โดยปริยาย | Server & API |
export let (legacy) | วิธีของ Svelte 4 ในการประกาศ prop เมื่อ component ใช้ rune ตัวใดก็ตาม export let จะกลายเป็น compile error จริง ๆ แทนที่จะเป็น warning เพราะการ rewrite reactivity ของ runes mode ไม่เหลือความหมายให้มันแล้ว — let { x } = $props() คือตัวแทนของ Svelte 5 | Events & Attributes |
| Term | ความหมาย | บทเรียน |
|---|---|---|
fail() | คืนค่าจาก form action ตอน validation ล้มเหลว (return fail(400, { error: '...' })) — มันไปถึง form prop ของหน้าเหมือนกับที่ plain object ที่คืนออกมาจะไปถึง แต่ต่างจาก plain object ตรงที่มันตั้ง HTTP status ที่ไม่ใช่ 200 จริง ๆ ด้วย ซึ่งเป็นสิ่งที่โค้ดที่แตกเงื่อนไขตาม response status ต้องการ | Forms & Actions |
flushSync | import จาก 'svelte' บังคับให้ effect ที่ค้างอยู่ทุกตัวรันทันทีแบบ synchronous — ต้องใช้หลังเรียก mount()/hydrate() ตรง ๆ (ซึ่งคืนค่าก่อนที่ effect จะรัน) หรือเวลาที่โค้ดแบบ imperative ต้องการให้ DOM ตามทันทีตอนนั้นเลย เช่นใน test | Lifecycle |
| form action | named export (หรือ default) ใน +page.server.js ที่ <form method="POST"> ยิงมาหา ทำงานได้โดยไม่ต้องมี JavaScript ฝั่ง client เลยแม้แต่น้อย — POST แบบ HTTP จริง ๆ, redirect หรือ re-render จริง ๆ — ก่อนที่ use:enhance จะเลือกอัปเกรดให้เป็น AJAX submission ได้ | Forms & Actions |
fromAction | แปลง action แบบ use: เดิม (รูปแบบ (node, params?) => { update?, destroy? }) ให้กลายเป็น attachment โดยพฤติกรรมเหมือนเดิมทุกอย่าง ทำให้ action ของ library ใช้กับ {@attach} ได้ — รวมถึงใช้กับ component ได้ด้วย ซึ่ง use: ดิบ ๆ ทำไม่ได้ | Actions |
fromStore / toStore | function เชื่อมระหว่างโลก reactivity สองแบบ: fromStore(store) ห่อ Svelte store ให้กลายเป็น runed object ที่มี property .current (อ่านใน $derived/template ได้โดยไม่ต้องมี $ นำหน้า) ส่วน toStore(getter, setter?) ทำกลับด้าน คือเปิด runed state ผ่าน contract subscribe แบบ store คลาสสิก | Runes vs Stores |
get() | อ่านค่าปัจจุบันของ store ครั้งเดียว นอก component โดยไม่ subscribe — implement (ใน svelte/store) ด้วยการ subscribe, จับค่าจากการเรียกแบบ synchronous ครั้งแรก แล้ว unsubscribe ทันที สะดวกก็จริง แต่ไม่ได้ฟรี เพราะยังต้องเสียรอบ subscribe/unsubscribe อยู่ดี | The Store Contract |
hooks (handle, sequence, handleFetch, handleError, reroute, transport) | พื้นผิวเต็มของ src/hooks.server.js: handle รันทุก request ก่อนถึง route ที่ match (ประกอบหลายตัวเข้าด้วยกันผ่าน sequence), handleFetch เขียนทับผลของ fetch ฝั่ง server เอง, handleError รันตอนเจอ exception ที่ไม่คาดคิด (ไม่ใช่ error()), reroute เขียนทับว่า URL จะ resolve ไป route ไหน และ transport serialize class instance แบบกำหนดเองข้าม boundary server/client | Server & API |
$host() | คืน DOM element ที่ host component ที่ compile เป็น custom element — เป็นจุดเชื่อมต่อเดียวกับโลกภายนอกในโหมดนั้น เพราะไม่มี parent component แบบ Svelte ให้รับ callback prop หรือ dispatch event ปกติ เรียกมันนอก component ที่เป็น custom element จะเป็น compile error จริง ๆ | Advanced Runes |
| hydration | ขั้นตอนที่ client ผูก event handler กับ state เข้ากับ HTML ที่ server render มาแล้ว แทนที่จะสร้างใหม่ตั้งแต่ต้น SvelteKit render ฝั่ง server (SSR) ก่อนเป็นค่า default แล้วค่อย hydrate ฝั่ง client — module-scope $state singleton ที่แชร์กันข้ามทุก request คือตัวอย่างคลาสสิกที่พังเพราะเรื่องนี้ | SvelteKit: Full-Stack Svelte |
| Term | ความหมาย | บทเรียน |
|---|---|---|
$inspect | log argument ของมันและ log ใหม่ทุกครั้งที่ค่าใดค่าหนึ่งเปลี่ยน — เครื่องมือที่ใช้เฉพาะตอน development (กลายเป็น no-op ใน production build) ต่างจาก console.log ธรรมดาตรงที่มัน track ค่าแบบเดียวกับ $derived/$effect แล้วรายงานทุก update ที่ตามมา | Advanced Runes |
$inspect.trace | วางเป็น statement แรกในสุดข้างใน effect หรือ derived แล้วมันจะพิมพ์ว่าการอ่านค่าตัวไหนที่ทำให้รอบนั้นเกิดขึ้น — เป็นเครื่องมือที่เจาะจงกว่า $inspect ธรรมดา เวลาที่ function มี dependency เยอะแล้วต้องหาว่าตัวไหนคือต้นเหตุ ใช้ได้เฉพาะตอน dev เหมือน $inspect | Advanced Runes |
{#key} | block ที่ทำลายแล้วสร้างเนื้อหาข้างในใหม่ทุกครั้งที่ค่าของ key expression เปลี่ยน — วิธีมาตรฐานในการเล่น transition ใหม่ตอนที่ ค่า เปลี่ยน ไม่ใช่แค่ตอน block รอบนอก add/remove เท่านั้น | Transitions & Animations |
load (universal vs server) | load แบบ universal ใน +page.js/+layout.js รันบน server ตอน SSR แล้วรันอีกครั้งฝั่ง client เวลา navigate ครั้งถัดไป (ดังนั้นต้องปลอดภัยที่จะรันได้ทุกที่); load แบบ server-only ใน +page.server.js/+layout.server.js รันเฉพาะฝั่ง server เท่านั้น เป็นที่ที่ต้องใช้เวลาจะเรียก database, secret หรือ env variable ส่วนตัว | Loading Data |
module state (.svelte.ts) | ไฟล์ .svelte.ts/.svelte.js ประกาศ $state ที่ module scope ได้ ให้ที่ไหนก็ import ไปใช้ ผู้ import ทุกคนแชร์ object ตัวเดียวกันเป๊ะ ๆ — instance เดียวสำหรับทั้ง process ที่กำลังรัน ปลอดภัยสำหรับข้อมูล global จริง ๆ แต่มีความเสี่ยงข้อมูลรั่วระหว่างผู้ใช้จริง ๆ ภายใต้ SSR ที่ process เดียวรับหลาย request | The $state Rune |
mount / hydrate | API แบบ imperative (จาก 'svelte') ที่ใช้ bootstrap entry point ของแอป Svelte ที่ไม่ใช่ SvelteKit: mount() render component ใหม่ทั้งหมดลงใน target element ส่วน hydrate() เกาะกับ HTML ที่ server render มาแล้วแทน ทั้งคู่คืนค่าก่อนที่ $effect ใด ๆ จะรัน เพราะ effect ถูก schedule ไว้บน microtask | Lifecycle |
| Term | ความหมาย | บทเรียน |
|---|---|---|
onclick vs on:click | event handler ใน Svelte 5 เป็น property ธรรมดา (onclick={handler}) แทนที่จะเป็น directive on:click={handler} ของ Svelte 4 รูปแบบเก่ายังคอมไพล์ผ่านอยู่วันนี้ (Svelte 5.57.1) พร้อม deprecation warning และ event modifier แบบ `on:click | preventDefaultหายไปแล้วใน 5 — ให้เรียกe.preventDefault()` ข้างใน handler แทน |
+page.svelte / +page.server.ts / +layout | ไฟล์พิเศษที่ SvelteKit อ่านจาก src/routes/: +page.svelte ทำให้ folder นั้นกลายเป็นหน้าที่ navigate ได้, +page.server.ts ให้ load/action ฝั่ง server-only ของหน้านั้น และ +layout.svelte ห่อทุก route ที่อยู่ข้างใต้มัน (ซ้อนกันได้ และ render child ที่ active อยู่ผ่าน snippet children) | Routing & Pages |
| param matcher | function ใน src/params/ (type ParamMatcher) ที่ segment แบบ dynamic อย่าง [id=integer] ต้องผ่านเงื่อนไขถึงจะ match ได้ ถ้าไม่ผ่าน SvelteKit จะตกไปหา route อื่นที่ตำแหน่งเดียวกันแทนที่จะบังคับ match route แบบ dynamic เสมอ | Routing & Pages |
pending / failed / onerror | snippet/prop ที่ตั้งชื่อไว้ของ <svelte:boundary>: pending โชว์ตอนที่ await ที่อยู่ตรง ๆ ข้างใน template ของ boundary ยังไม่ resolve เฉพาะ render รอบแรกเท่านั้น; failed (พร้อม callback reset()) render แทนที่ subtree ที่ render หรือ effect ของมัน throw; onerror สังเกต error ที่ throw ออกมาได้ แต่ห้ามเรียก reset() แบบ synchronous จากข้างในตัวมันเอง | Lifecycle |
| prerender | export const prerender = true ใน +page.server.js/+page.js render route นั้นเป็นไฟล์ static ตอน build time แทนที่จะ render ทุก request — ทางเลือกของ render mode ที่แลกความสดใหม่ต่อ request กับการไม่ต้องเสีย server ทำงานเลยตอน runtime | Server & API |
$props | destructure input ของ component จาก parent (let { name, greeting = 'Hello' } = $props()) แทนที่ export let ของ Svelte 4 มันรองรับชุดเครื่องมือ destructure ปกติ — ค่า default, การ rename และ rest pattern (...rest) สำหรับส่งต่อ attribute ที่เหลือ | Props & $bindable |
$props.id | สร้าง id ที่ไม่ซ้ำกันให้ instance ของ component ตัวนั้น ๆ โดยที่ ตรงกันระหว่าง server กับ client ตอน hydration — ตรงกับสิ่งที่ต้องใช้เชื่อม <label for> เข้ากับ <input id> โดยไม่ต้องใช้ string ตายตัวที่จะชนกันเมื่อ component ถูกใช้ซ้ำสองครั้งบนหน้าเดียวกัน | Passing UI & Children |
| push/pull (lazy derived) | โมเดลเบื้องหลังความ lazy ของ $derived: dependency ที่เปลี่ยนจะ push notification “แกเดี๋ยว dirty” ให้ แต่ function จะถูก pull (รันจริง) ก็ต่อเมื่อมีอะไรมาอ่านค่า derived นั้นครั้งถัดไปเท่านั้น — พิสูจน์แล้วว่า derived ที่เปลี่ยน dependency ห้าครั้งโดยไม่มีการอ่านคั่นกลางเลย จะประเมินค่าเป็นศูนย์ครั้งพอดี | The $derived Rune |
| Term | ความหมาย | บทเรียน |
|---|---|---|
reactive declarations ($:, legacy) | syntax แบบ reactive statement ของ Svelte 4 ($: doubled = count * 2) ที่ compiler ในโหมด legacy เขียนใหม่ให้กลายเป็นโค้ด dependency-tracking ของตัวเอง การผสมมันเข้ากับ component ที่อยู่ใน runes mode เป็น compile error จริง ๆ ไม่ใช่แค่ warning — $derived/$effect คือตัวแทนของ Svelte 5 | Events & Attributes |
redirect() / error() | helper ควบคุมการทำงานของ SvelteKit ที่ทำงานผ่านการ throw — redirect(status, location) กับ error(status, message) — ดังนั้น try/catch ที่ห่อโค้ดที่อาจเรียกมันต้องเช็ก isRedirect/isHttpError ก่อนจะถือว่าค่าที่ catch ได้เป็น failure จริง ไม่งั้นมันจะกลืน redirect/error ไปเงียบ ๆ | Server & API |
| remote functions (experimental) | ทางเลือกทดลองแทน load/action/+server.js สำหรับคุยกับ server: query, form, command และ prerender จาก $app/server เรียกใช้คล้าย function ธรรมดามากกว่าการ submit form — ยังไม่ stable ตามที่ระบุไว้ชัดเจน ควรรู้จักไว้แต่ยังไม่ควรสร้างโค้ด production บนมันโดยไม่เช็กสถานะซ้ำก่อน | Forms & Actions |
{@render} | render snippet ({@render name(args)}) การเขียนชื่อ snippet เป็นการเรียกธรรมดาแทน ({row(item)}) จะคอมไพล์ผ่านโดยไม่มี error เลย แต่จะ throw error จริง ๆ ตอน runtime ทันทีที่บรรทัดนั้นถูกรัน เพราะ snippet คอมไพล์ออกมาเป็น function ที่คาดหวัง argument พิเศษที่ {@render} เป็นคนใส่ให้ | Snippets & Render |
| route | หน่วยของโครงสร้าง URL แบบ file-based ของ SvelteKit: โครงสร้าง folder ใต้ src/routes/ คือ โครงสร้าง URL เลย โดยวงเล็บเหลี่ยม ([slug], [...rest], [[optional]]) ใช้จับ segment แบบ dynamic | Routing & Pages |
| route group | ชื่อ folder ที่ห่อด้วยวงเล็บ ((app)) ที่จัดกลุ่ม route — และถือ +layout.svelte ที่ใช้ร่วมกันได้ — โดยไม่เพิ่ม segment เข้าไปใน URL src/routes/(app)/grouped/+page.svelte ก็ยังเป็นแค่ /grouped | Routing & Pages |
| rune | compiler signal — คำคล้าย function ที่มี $ นำหน้า ($state, $derived, $effect, $props, …) ที่บอก Svelte ว่าค่านี้ reactive rune ไม่ได้ถูก import และไม่ได้ถูกเรียกตอน runtime แบบ function ปกติ compiler จำมันได้เองแล้วสร้างกลไก reactivity รอบ ๆ มันโดยตรง | Reactivity with Runes |
| Term | ความหมาย | บทเรียน |
|---|---|---|
settled() | import จาก 'svelte' คืน promise ที่ resolve เมื่อ state-triggered UI update ที่ค้างอยู่ถูก apply ครบแล้ว มีไว้ใช้กับกรณี batch การเขียน $state แบบ synchronous ธรรมดาตามเอกสาร ไม่ใช่ไว้รอ {await}/boundary render ที่กำลังทำงานอยู่ ซึ่งเป็นการใช้ผิดที่พบบ่อย | Async Svelte |
| signal | คำเรียกทั่วไปของ primitive แบบ reactive ที่อยู่เบื้องหลัง rune — เอกสารของ Svelte เองเรียก rune ว่าเป็น “compiler signal” การอ่านค่าลงทะเบียน dependency และการเขียนค่าแจ้ง dependent เป็นกลไก push-pull เดียวกับที่ $state/$derived/$effect ใช้ร่วมกันหมด | Reactivity with Runes |
| slot (legacy) | วิธีของ Svelte 4 ในการส่ง markup เข้า component (<slot />, <slot name="x">) ถูกแทนที่ทั้งหมดใน Svelte 5 ด้วย snippet <slot> วันนี้ (Svelte 5.57.1) ยังคอมไพล์ผ่านและทำงานได้อยู่ พร้อม deprecation warning ไม่ใช่ถูกเอาออกไปแล้ว | Snippets & Render |
| snippet | ก้อน markup ที่ตั้งชื่อไว้และนำกลับมาใช้ซ้ำได้ ประกาศด้วย {#snippet name(params)}…{/snippet} แล้ว render ด้วย {@render name(args)} snippet รับ parameter ได้เหมือน function และเป็นตัวแทนของ <slot> ใน Svelte 5 | Snippets & Render |
Snippet<[T]> | type ของ TypeScript สำหรับ snippet prop import จาก 'svelte': Snippet เฉย ๆ หมายถึงไม่รับ parameter เลย ส่วน Snippet<[T]> หมายถึงรับ parameter หนึ่งตัวชนิด T (array คือ tuple เพราะ snippet รับได้หลาย parameter) เมื่อรวมกับ generic บนตัว component มันจะผูก type ของ item ข้อมูลเข้ากับ parameter ของ snippet ที่ render มันได้ | Passing UI & Children |
| spread attributes | {...obj} ใส่ attribute ทั้ง object ลงบน element ทีเดียว attribute จะถูก apply ตามลำดับที่เขียนใน markup ดังนั้นไม่ว่าจะเป็น spread หรือ attribute ที่เขียนตรง ๆ ตัวที่เขียนอยู่ทีหลังจะชนะ — ไม่มีระบบ priority แยกต่างหากนอกจากลำดับนี้ | Events & Attributes |
| SSR | server-side rendering: SvelteKit render HTML ของ route บน server เป็นค่า default ก่อนที่ client จะ hydrate — โหมดนี้เองที่ทำให้ module-scope $state singleton อันตราย (แชร์กันข้ามทุก request ที่เกิดพร้อมกันบน process นั้น) ถ้าไม่สร้าง state ใหม่ต่อ request ผ่าน context แทน | SvelteKit: Full-Stack Svelte |
$state | ประกาศค่า reactive (let count = $state(0)) บน object หรือ array มันห่อค่าด้วย Proxy เพื่อให้เกิด deep reactivity ดังนั้นการเขียน property ธรรมดาและการ mutate array จะถูก track ไม่ใช่แค่การ assign ค่าทั้งก้อนใหม่เท่านั้น | The $state Rune |
$state.raw | ทำให้ค่าหลุดออกจาก Proxy ที่ $state ปกติจะห่อให้กับ object/array — มีแค่การ reassign ตัวแปรทั้งก้อนเท่านั้นที่นับเป็นการเขียน การ mutate เนื้อหาข้างในเปลี่ยนข้อมูลจริงแต่ไม่แจ้งใครเลย แลก deep reactivity กับประสิทธิภาพที่ได้จากการข้าม proxy instrumentation | The $state Rune |
$state.snapshot | เอาสำเนาแบบธรรมดาที่ไม่ผ่าน proxy ของค่า $state ออกมา — ไว้ส่งให้ API (api.save(...)) หรือโค้ดใด ๆ ที่ไม่คาดหวัง (หรือจะทำงานผิดพลาดกับ) Proxy โดยไม่กระทบ reactive state ต้นฉบับ | The $state Rune |
$store auto-subscription | การใส่ $ นำหน้า store ข้างในไฟล์ .svelte/.svelte.js เป็น syntax sugar ของ compiler ที่ subscribe ให้แทนเรา อ่านค่าปัจจุบัน re-render ตอนเปลี่ยน และ unsubscribe อัตโนมัติตอน destroy — แต่ใช้ได้แค่ที่ top level ของ component เท่านั้น ไม่ใช่ข้างในฟังก์ชันหรือ block ที่ซ้อนอยู่ เพราะ compiler วาง subscription แบบ static ตรงนั้นไม่ได้ | The Store Contract |
| store contract | นิยามทั้งหมดของ Svelte store: object ใดก็ตามที่มี method subscribe(fn) ที่เรียก fn ทันทีด้วยค่าปัจจุบัน แล้วเรียกอีกทุกครั้งที่เปลี่ยน คืน function สำหรับ unsubscribe กลับมา — แค่นี้ก็พอแล้ว นี่คือเหตุผลที่ RxJS observable หรือ object ของ library อื่น ๆ ก็เป็น store ได้เหมือนกัน | The Store Contract |
| streaming (un-awaited promise) | การคืน promise จาก load โดยไม่ await มัน ทำให้ SvelteKit ส่งส่วนที่เหลือของหน้าออกไปทันที แล้วค่อย stream ค่านั้นเข้ามาทีหลังตอนมัน resolve อ่านได้ฝั่ง client ด้วย {#await} — ตรงข้ามกับการ await มันตรง ๆ ใน load ซึ่งจะทำให้ response แรกต้องรอจนกว่ามันจะเสร็จ | Loading Data |
<svelte:boundary> | กัก error ของ render หรือ effect ที่ throw ที่ไหนก็ตามใน subtree ของมันไว้ แทนที่จะปล่อยให้มัน unmount component tree ทั้งก้อนรอบข้าง มันยังโชว์ snippet pending ระหว่างที่ await ที่อยู่ตรง ๆ ใน template ของมันเอง resolve ครั้งแรก — ทั้ง async และ error handling อยู่บน element เดียวกัน | Lifecycle |
svelte-check | type-checker แบบ command-line (ปกติ npm run check จะรันมัน) ที่เข้าใจไฟล์ .svelte แบบครบวงจร — รวมถึง expression ข้างใน markup ด้วย จับ prop type ที่ผิดหรือ typo ใน template ที่ tsc ธรรมดาจะพลาดไปเลยได้ | Project & Tooling |
svelte/events on | function ที่ผูก listener แล้วคืน cleanup ให้ในการเรียกครั้งเดียว สำหรับกรณีที่ attribute ธรรมดาแสดงออกไม่ได้ — option passive/once หรือโค้ดที่ต้องอยู่ร่วมกับการ dispatch แบบ delegate ของ Svelte และการจัดการ stopPropagation() ของมันให้ถูกต้อง ใช้ข้างใน attachment หรือ $effect ไม่ใช่เป็น attribute ใน template | Events & Attributes |
| svelte-migrate | codemod CLI ทางการ (npx svelte-migrate) ที่ช่วย automate การ rewrite จาก Svelte 4 ไป 5 ส่วนใหญ่ — export let ไปเป็น $props(), $: ไปเป็น $derived/$effect — สำหรับ pattern แบบ legacy ชุดเดียวกับที่คอร์สนี้สอนให้จำได้ด้วยมือ ไม่ได้ถูกใช้จริงใน probe ของคอร์สนี้โดยตรง ให้มองว่านี่เป็นการชี้ทางที่ถูกต้อง มากกว่าข้อเท็จจริงที่พิสูจน์เองในคอร์ส | Events & Attributes |
svelte/reactivity (SvelteMap …) | ตั้งแต่ Svelte 5.8 มี class reactive แบบ rune-native — SvelteMap, SvelteSet, SvelteDate, SvelteURL, SvelteURLSearchParams, MediaQuery — ที่ track การอ่านค่าและการเรียก method เหมือน $state โดยไม่มี subscribe/$/store contract เลย ต่างจาก Map ธรรมดาที่ห่อด้วย $state ตรงที่ SvelteMap ทำให้ .set()/.delete() เองก็ reactive ไม่ใช่แค่การแทนที่ค่าทั้งก้อน | Built-in Stores |
svelte/reactivity/window | ค่า reactive แบบ rune-native สำหรับ global ของ browser (innerWidth, scrollY, online, …) แทนที่ listener แบบ resize/scroll/online ที่เขียนเอง มันอ่าน property จริงของ window ดังนั้น — เหมือนค่าที่มาจาก window ทุกตัว — ให้คาดหวังว่าอาจเกิด hydration mismatch ได้ตอน SSR ไม่ใช่ค่าฝั่ง server ที่ถูกต้องเสมอไป | Built-in Stores |
| Term | ความหมาย | บทเรียน |
|---|---|---|
tick | await tick() resolve เมื่อ batch ของ DOM update ที่ค้างอยู่ตอนนี้ถูก apply เสร็จแล้ว — สำหรับกรณีที่พบไม่บ่อยอย่างการวัดขนาด element หรือ focus ที่ input ที่เพิ่งโชว์ทันทีหลัง state เปลี่ยน ก่อนที่บรรทัดถัดไปจะรัน | Lifecycle |
transition / in: / out: / |global | transition: ทำ animation ให้ทั้งตอน element เข้ามาและออกไป; in:/out: ใส่ animation ต่างกันให้แต่ละด้านแยกจากกันได้ transition เป็นแบบ local เป็นค่า default — มันจะเล่นก็ต่อเมื่อ block ที่มันอยู่ตรง ๆ ถูกสร้างหรือทำลายเท่านั้น — และ |global เปิดให้มันเล่นซ้ำเมื่อ ancestor block ไหนก็ตาม ถูกสร้างหรือทำลายแทน | Transitions & Animations |
untrack | ให้ effect (หรือ derived) อ่านค่า reactive ได้โดยไม่เพิ่มมันเป็น dependency ทำให้การเปลี่ยนค่านั้นอย่างเดียวไม่ trigger การรันใหม่ — import จาก 'svelte' เป็นทางออกสำหรับกรณีที่พบไม่บ่อยที่การอ่านค่าบางอย่างต้องไม่ reactive ด้วยตัวมันเอง | The $effect Rune |
use:enhance | อัปเกรด action ของ <form method="POST"> ธรรมดาให้เป็น AJAX submission แบบค่อยเป็นค่อยไป โดยไม่ต้องแก้ฝั่ง server เลย ใช้เปล่า ๆ ก็แค่หลีกเลี่ยงการ navigate ทั้งหน้าตอนสำเร็จ หรือถ้าใส่ callback (use:enhance={fn}) callback นั้นจะได้ควบคุมเต็มที่ผ่าน update()/applyAction() | Forms & Actions |
vite-plugin-svelte | @sveltejs/vite-plugin-svelte ที่ sv create เชื่อมต่อให้อัตโนมัติ — ตัวที่รัน compiler ของ Svelte บนไฟล์ .svelte จริง ๆ ระหว่าง dev server และ build ของ Vite โค้ดวันต่อวันแทบไม่ต้องแตะมันโดยตรงเลย | Project & Tooling |
| Term | ความหมาย | บทเรียน |
|---|---|---|
writable derived (assignable $derived) | ตั้งแต่ Svelte 5.25 ค่า $derived ที่ประกาศด้วย let reassign ตรง ๆ ได้เลย (likes += 1) สำหรับ optimistic UI — ค่าที่ทับไว้จะเห็นผลทันทีและอยู่จนกว่า dependency จริงจะเปลี่ยนแล้วบังคับให้คำนวณใหม่ ตอนนั้นมันจะกลับไปเป็นค่า derived เหมือนเดิม ส่วน const $derived ยังคง reassign ไม่ได้ | The $derived Rune |
writable / readable / derived (store helpers) | ตัวสร้าง store สามตัวจาก svelte/store: writable(initial) ให้ set/update/subscribe; readable(initial, start) ให้ค่าที่มีแค่ function start ของตัวมันเองเท่านั้นที่ set ได้ เหมาะกับการห่อแหล่งข้อมูลภายนอกแบบ push; derived(stores, fn) คำนวณค่าของ store จาก store อื่นตั้งแต่หนึ่งตัวขึ้นไป | Built-in Stores |