Web Development

Svelte 5 Runes CI/CD Automation Pipeline

svelte 5 runes ci cd automation pipeline
Svelte 5 Runes CI/CD Automation Pipeline | SiamCafe Blog

โดย อ. บอมกิตติทัศน์เจริญพนาสิทธิ์ | อัปเดต 24 ก. พ. 2026 | อ่าน 15 นาที

Svelte 5 คืออะไร — เปลี่ยนแปลงจาก Svelte 4

Svelte เป็น Frontend Framework ที่แตกต่างจาก React และ Vue ตรงที่ Svelte เป็น Compiler ไม่ใช่ Runtime Library คอมไพล์ Component เป็น Vanilla JavaScript ที่ Optimized ทำให้ Bundle Size เล็กมากและ Performance สูงไม่มี Virtual DOM Overhead

Svelte 5 เปิดตัวปลายปี 2024 มีการเปลี่ยนแปลงใหญ่ที่สุดคือ Runes ระบบ Reactivity ใหม่ที่ชัดเจนกว่า Svelte 4 ใช้ Compiler Magic ที่ let x = 0 กลายเป็น Reactive อัตโนมัติแต่ปัญหาคือบางครั้งงงว่า Variable ไหน Reactive ไหนไม่ Runes แก้ปัญหานี้โดยใช้ $state(), $derived(), $effect() อย่างชัดเจน

Runes — ระบบ Reactivity ใหม่

Runeหน้าที่เทียบกับ React
$state()สร้าง Reactive StateuseState()
$derived()คำนวณจาก State (Read-only)useMemo()
$effect()รัน Side Effect เมื่อ State เปลี่ยนuseEffect()
$props()รับ Props จาก Parentfunction Component(props)
$bindable()Props ที่ Bind สองทางได้ไม่มีเทียบตรง
$inspect()Debug: Log เมื่อ State เปลี่ยนconsole.log ใน useEffect

$state — สร้าง Reactive State

<script>
 // Svelte 5 — ใช้ $state()
 let count = $state(0)
 let user = $state({ name: 'สมชาย', age: 30 })
 let items = $state(['Apple', 'Banana', 'Cherry'])

 function increment() {
 count++ // Reactive! UI อัปเดตอัตโนมัติ
 }

 function addItem() {
 items.push('New Item') // Reactive Array Mutation!
 // Svelte 5: Array/Object mutation ทำงานได้เลย
 // ไม่ต้อง items = [...items, 'New Item'] แบบ Svelte 4
 }

 function updateName() {
 user.name = 'สมหญิง' // Reactive Object Mutation!
 }
</script>

<button onclick={increment}>Count: {count}</button>
<button onclick={addItem}>Add Item ({items.length})</button>
<button onclick={updateName}>{user.name}</button>

$derived — Computed Value

<script>
 let price = $state(100)
 let quantity = $state(2)
 let vat = $state(7)

 // $derived คำนวณอัตโนมัติเมื่อ Dependencies เปลี่ยน
 let subtotal = $derived(price * quantity)
 let vatAmount = $derived(subtotal * vat / 100)
 let total = $derived(subtotal + vatAmount)

 // $derived กับ Complex Logic
 let items = $state([
 { name: 'Item A', price: 100, qty: 2 },
 { name: 'Item B', price: 200, qty: 1 }
 ])
 
 let cartTotal = $derived(
 items.reduce((sum, item) => sum + item.price * item.qty, 0)
 )
</script>

<p>Subtotal: ฿{subtotal}</p>
<p>VAT ({vat}%): ฿{vatAmount}</p>
<p>Total: ฿{total}</p>

$effect — Side Effects

<script>
 let searchQuery = $state('')
 let results = $state([])

 // $effect รันเมื่อ searchQuery เปลี่ยน
 $effect(() => {
 if (searchQuery.length < 3) {
 results = []
 return
 }
 
 // Debounce ด้วย Cleanup Function
 const timer = setTimeout(async () => {
 const res = await fetch(`/api/search?q=`)
 results = await res.json()
 }, 300)

 // Cleanup: ล้าง Timer เมื่อ searchQuery เปลี่ยนอีก
 return () => clearTimeout(timer)
 })

 // $effect สำหรับ LocalStorage Sync
 let theme = $state('dark')
 
 $effect(() => {
 localStorage.setItem('theme', theme)
 document.documentElement.setAttribute('data-theme', theme)
 })

 // $inspect สำหรับ Debug (Dev Only)
 $inspect(searchQuery, results)
</script>

<input bind:value={searchQuery} 

$props และ $bindable — Component Communication

<!-- TextInput.svelte -->
<script>
 let { 
 label, 
 value = $bindable(''), // Two-way Binding
 

Snippets แทน Slots — Template Reuse

<!-- Svelte 5: Snippets แทน Slots -->
<script>
 let items = $state(['Apple', 'Banana', 'Cherry'])
</script>

{#snippet row(item, index)}
 <tr>
 <td>{index + 1}</td>
 <td>{item}</td>
 <td><button onclick={() => items.splice(index, 1)}> ลบ</button></td>
 </tr>
{/snippet}

<table>
 {#each items as item, i}
 {@render row(item, i)}
 {/each}
</table>

SvelteKit — Full-stack Framework

// สร้าง SvelteKit Project
npx sv create my-app
cd my-app
npm install
npm run dev

// src/routes/+page.server.ts — Server-side Data Loading
import type { PageServerLoad } from './$types'
import { db } from '$lib/server/db'

export const load: PageServerLoad = async () => {
 const posts = await db.post.findMany({
 orderBy: { createdAt: 'desc' },
 take: 10
 })
 return { posts }
}

// src/routes/+page.svelte — Display Data
<script>
 let { data } = $props()
</script>

{#each data.posts as post}
 <article>
 <h2>{post.title}</h2>
 <p>{post.excerpt}</p>
 </article>
{/each}

Testing — Vitest และ Playwright

// vitest.config.ts
import { defineConfig } from 'vitest/config'
import { svelte } from '@sveltejs/vite-plugin-svelte'

export default defineConfig({
 plugins: [svelte({ hot: false })],
 test: {
 include: ['src/**/*.test.ts'],
 environment: 'jsdom',
 setupFiles: ['./vitest-setup.ts']
 }
})

// src/lib/Counter.test.ts — Unit Test
import { render, fireEvent } from '@testing-library/svelte'
import { expect, test } from 'vitest'
import Counter from './Counter.svelte'

test('increments count on click', async () => {
 const { getByText } = render(Counter)
 const button = getByText('Count: 0')
 await fireEvent.click(button)
 expect(getByText('Count: 1')).toBeTruthy()
})

// tests/e2e/home.test.ts — Playwright E2E
import { test, expect } from '@playwright/test'

test('home page loads', async ({ page }) => {
 await page.goto('/')
 await expect(page.locator('h1')).toContainText('Welcome')
})

test('search works', async ({ page }) => {
 await page.goto('/')
 await page.fill('input[

CI/CD Pipeline ด้วย GitHub Actions

# .github/workflows/ci-cd.yml
name: CI/CD Pipeline

on:
 push:
 branches: [main, develop]
 pull_request:
 branches: [main]

jobs:
 lint-and-check:
 runs-on: ubuntu-latest
 steps:
 - uses: actions/checkout@v4
 - uses: actions/setup-node@v4
 with:
 node-version: 22
 cache: 'npm'
 - run: npm ci
 - run: npm run lint
 - run: npm run check # svelte-check (TypeScript)

 unit-test:
 runs-on: ubuntu-latest
 needs: lint-and-check
 steps:
 - uses: actions/checkout@v4
 - uses: actions/setup-node@v4
 with: { node-version: 22, cache: 'npm' }
 - run: npm ci
 - run: npm run test:unit -- --coverage
 - uses: actions/upload-artifact@v4
 with:
 name: coverage
 path: coverage/

 e2e-test:
 runs-on: ubuntu-latest
 needs: lint-and-check
 steps:
 - uses: actions/checkout@v4
 - uses: actions/setup-node@v4
 with: { node-version: 22, cache: 'npm' }
 - run: npm ci
 - run: npx playwright install --with-deps
 - run: npm run build
 - run: npm run test:e2e
 - uses: actions/upload-artifact@v4
 if: failure()
 with:
 name: playwright-report
 path: playwright-report/

 deploy-staging:
 runs-on: ubuntu-latest
 needs: [unit-test, e2e-test]
 if: github.ref == 'refs/heads/develop'
 steps:
 - uses: actions/checkout@v4
 - uses: actions/setup-node@v4
 with: { node-version: 22, cache: 'npm' }
 - run: npm ci
 - run: npm run build
 env:
 PUBLIC_API_URL: }
 - name: Deploy to Staging
 run: npx wrangler pages deploy .svelte-kit/cloudflare --project-name=my-app-staging
 env:
 CLOUDFLARE_API_TOKEN: }

 deploy-production:
 runs-on: ubuntu-latest
 needs: [unit-test, e2e-test]
 if: github.ref == 'refs/heads/main'
 steps:
 - uses: actions/checkout@v4
 - uses: actions/setup-node@v4
 with: { node-version: 22, cache: 'npm' }
 - run: npm ci
 - run: npm run build
 env:
 PUBLIC_API_URL: }
 - name: Deploy to Production
 run: npx wrangler pages deploy .svelte-kit/cloudflare --project-name=my-app
 env:
 CLOUDFLARE_API_TOKEN: }

Deploy บน Vercel / Cloudflare / Netlify

// svelte.config.js — เลือก Adapter ตาม Platform

// Vercel
import adapter from '@sveltejs/adapter-vercel'

// Cloudflare Pages
import adapter from '@sveltejs/adapter-cloudflare'

// Netlify
import adapter from '@sveltejs/adapter-netlify'

// Node.js Server
import adapter from '@sveltejs/adapter-node'

export default {
 kit: {
 adapter: adapter({
 // Vercel options
 runtime: 'edge', // หรือ 'nodejs22.x'
 regions: ['sin1'], // Singapore
 
 // Node.js options
 // out: 'build',
 // precompress: true
 })
 }
}

Performance Optimization

Best Practices และสรุป

Svelte 5 Runes ทำให้ Reactivity ชัดเจนและ Predictable มากขึ้นเมื่อรวมกับ CI/CD Pipeline ที่ครอบคลุมจะได้ Development Workflow ที่รวดเร็วปลอดภัยและ Scalable ติดตามบทความใหม่ๆได้ที่ SiamCafe.net

อ. บอมกิตติทัศน์เจริญพนาสิทธิ์
IT Infrastructure Expert | Thaiware Award | ประสบการณ์กว่า 25 ปี — ผู้ก่อตั้ง SiamCafe.net Since 2000-2026

Q: Svelte 5 Runes คืออะไร

ระบบ Reactivity ใหม่ใช้ $state(), $derived(), $effect() ชัดเจนกว่า Svelte 4 ที่ใช้ let keyword เป็น Reactive อัตโนมัติ

Q: $state กับ $derived ต่างกันอย่างไร

$state = Mutable Reactive Value เปลี่ยนค่าได้ | $derived = Read-only Computed Value คำนวณจาก State อื่นอัปเดตอัตโนมัติ

Q: CI/CD สำหรับ SvelteKit ทำอย่างไร

GitHub Actions: Lint → svelte-check → Unit Test (Vitest) → E2E (Playwright) → Build → Deploy (Vercel/Cloudflare/Netlify)

Q: SvelteKit คืออะไร

Full-stack Framework ของ Svelte (เหมือน Next.js ของ React) รองรับ SSR, SSG, API Routes, Form Actions Deploy ได้หลาย Platform

บทความแนะนำ:

อ่านเพิ่มเติม: บทความทั้งหมด | หน้าแรก Blog

เจาะลึก Svelte 5 Runes CI/CD Automation Pipeline

การทำความเข้าใจ Svelte 5 Runes CI/CD Automation Pipeline อย่างลึกซึ้งนั้นมีความสำคัญอย่างมากในยุคปัจจุบันเทคโนโลยีนี้ได้รับความนิยมเพิ่มขึ้นอย่างต่อเนื่องทั้งในระดับองค์กรและระดับบุคคลการเรียนรู้และทำความเข้าใจหลักการทำงานพื้นฐานจะช่วยให้คุณสามารถนำไปประยุกต์ใช้งานได้อย่างมีประสิทธิภาพมากยิ่งขึ้น

ในบริบทของประเทศไทย Svelte 5 Runes CI/CD Automation Pipeline มีบทบาทสำคัญในการพัฒนาโครงสร้างพื้นฐานด้านเทคโนโลยีสารสนเทศองค์กรต่างๆทั้งภาครัฐและเอกชนต่างให้ความสนใจในการนำเทคโนโลยีนี้มาใช้เพื่อเพิ่มประสิทธิภาพการทำงานและลดต้นทุนในระยะยาวความเข้าใจที่ถูกต้องจะช่วยให้การตัดสินใจเลือกใช้เครื่องมือและแนวทางปฏิบัติเป็นไปอย่างเหมาะสม