算法艺术创作
algorithmic-art
通过代码和可调参数创作生成艺术与交互式视觉效果。
sveltekit【设计与创意】Use this skill when building SvelteKit applications — routing, load functions, form actions, API endpoints, server-side rendering, stores, deployment. This skill enforces: file-based routing conventions, server load functions for data fetching, form actions with validation and redirects, separated API endpoints in routes/api. Do NOT use for: non-Svel…
独立 GitHub 快照 · 自动分类 · 以原作者文档为准
Define and enforce SvelteKit application architecture with routing conventions, data loading, form handling, and deployment patterns.
User request includes: svelte, sveltekit, svelte app, svelte routing, svelte load, svelte server, svelte form, svelte kit.
No file output. Produces route structure, load functions, form actions, and deployment config as text.
Route structure with file tree. Load and action code examples. Deployment config.
No preamble. No postamble. No explanations. No filler/hedging/transitions.
4096 tokens
| Approach | Trade-off | When to Use |
|---|---|---|
| Server load functions (+page.server.ts) | DB access, secrets, SSR | Private/personalized data |
| Universal load functions (+page.ts) | Runs on server + client | Public API data, cached |
| Form actions | Server mutations, progressive enhancement | All form submissions |
| API endpoints (+server.ts) | REST/JSON endpoints | External API consumption |
| Hooks (handle) | Per-request processing | Auth, logging, redirects |
Is the data user-specific?
├── Yes -> +page.server.ts or +layout.server.ts
└── No -> Is the API public?
├── Yes -> +page.ts (universal load)
└── No -> +page.server.ts
How should this route render?
├── Needs SEO + fast initial load -> SSR (default)
├── Fully static content -> export const prerender = true
├── Authenticated dashboard -> SSR + trailing slash
└── No SSR needed -> export const ssr = false
// src/routes/dashboard/+page.server.ts
import type { PageServerLoad } from './$types'
export const load: PageServerLoad = async ({ locals, url }) => {
if (!locals.user) throw redirect(302, '/login')
const page = Number(url.searchParams.get('page')) || 1
const [orders, total, notifications] = await Promise.all([
db.order.findMany({ where: { userId: locals.user.id }, skip: (page-1)*20, take: 20 }),
db.order.count({ where: { userId: locals.user.id } }),
db.notification.findMany({ where: { userId: locals.user.id, read: false } }),
])
return { user: locals.user, orders, total, page, notifications }
}
// src/routes/products/+page.ts
import type { PageLoad } from './$types'
export const load: PageLoad = async ({ fetch, url }) => {
const res = await fetch(`/api/products?${url.searchParams}`)
const products = await res.json()
return {
products,
/** Cache on CDN for 5 minutes, stale-while-revalidate for 1 hour */
headers: { 'Cache-Control': 'public, max-age=300, s-maxage=3600' },
}
}
// src/routes/settings/+page.server.ts
import type { Actions } from './$types'
import { fail, redirect } from '@sveltejs/kit'
import { z } from 'zod'
const schema = z.object({ name: z.string().min(2), email: z.string().email() })
export const actions: Actions = {
default: async ({ request, locals }) => {
const data = Object.fromEntries(await request.formData())
const result = schema.safeParse(data)
if (!result.success) return fail(400, { errors: result.error.flatten().fieldErrors, values: data })
await db.user.update({ where: { id: locals.user.id }, data: result.data })
return { success: true }
},
delete: async ({ locals }) => {
await db.user.delete({ where: { id: locals.user.id } })
throw redirect(302, '/goodbye')
},
}
// src/routes/api/orders/+server.ts
import { json } from '@sveltejs/kit'
import type { RequestHandler } from './$types'
export const GET: RequestHandler = async ({ locals, url }) => {
const orders = await db.order.findMany({ where: { userId: locals.user.id } })
return json(orders)
}
export const POST: RequestHandler = async ({ request, locals }) => {
const body = await request.json()
const order = await db.order.create({ data: { ...body, userId: locals.user.id } })
return json(order, { status: 201 })
}
<script>
let { data } = $props()
// data.orders, data.user from load function
</script>
<script>
import { enhance } from '$app/forms'
let { form, data } = $props()
</script>
<form method="POST" use:enhance>
<input name="name" bind:value={form?.name} />
<button type="submit">Save</button>
</form>
// src/lib/stores/cart.svelte.ts
import { writable } from 'svelte/store'
export const cart = writable<CartItem[]>([])
preload attributes on critical assetssetHeaders in load functions// svelte.config.js
import adapter from '@sveltejs/adapter-vercel' // or -node, -netlify, -cloudflare
export default {
kit: {
adapter: adapter({
runtime: 'edge', // for adapter-vercel
regions: ['iad1'],
}),
prerender: {
entries: ['/', '/about', '/blog/*'],
},
},
}
npm run build # adapter-specific build
npm run preview # preview production build
npm run dev # dev server with HMR
// Server-only: process.env.DATABASE_URL
// Public: import { env } from '$env/dynamic/public' or '$env/static/public'
// Private: import { env } from '$env/dynamic/private' or '$env/static/private'
import { describe, it, expect } from 'vitest'
import { load } from './+page.server'
it('returns orders for authenticated user', async () => {
const result = await load({ locals: { user: { id: '1' } }, url: new URL('http://localhost'), params: {} })
expect(result).toHaveProperty('orders')
expect(result).toHaveProperty('user')
})
it('validates form input', async () => {
const formData = new FormData()
formData.set('email', 'invalid')
const result = await actions.default({ request: new Request('http://localhost', { method: 'POST', body: formData }), locals: { user: { id: '1' } } })
expect(result.status).toBe(400)
})
import { test, expect } from '@playwright/test'
test('submits contact form', async ({ page }) => {
await page.goto('/contact')
await page.fill('[name="email"]', 'test@test.com')
await page.click('button[type="submit"]')
await expect(page).toHaveURL(/\/thanks/)
})
// Svelte 4
import { writable, derived } from 'svelte/store'
export const count = writable(0)
// Svelte 5
let count = $state(0)
| Express + SPA | SvelteKit |
|---|---|
| Express routes | +page.svelte + +page.server.ts |
| REST API | +server.ts |
| Session middleware | hooks.server.ts |
| Client fetch | load() functions |
throw redirect(), not return redirect()+page.server.ts load(), not onMount.throw redirect: Must be thrown, not returned.$page, $app/stores are client-only.+error.svelte.| Aspect | SvelteKit | Next.js App Router | Nuxt 3 |
|---|---|---|---|
| Data loading | load functions | async component + fetch | useAsyncData |
| Mutations | form actions | Server Actions | useFetch with method |
| API endpoints | +server.ts | route.ts | server/api/ |
| Bundle size | ~5KB runtime | ~70KB+ (React) | ~40KB (Vue) |
| Hydration | Per-component | Full-page | Full-page |
npm create svelte@latest — scaffoldnpm run dev — HMRnpm run build — adapter buildsvelte-check — CLI type checking@sveltejs/adapter-auto — automatic adaptersvelte-add — add integrationssrc/routes/
+page.svelte -- /
+layout.svelte -- root layout
+layout.server.ts -- shared data
orders/
+page.svelte -- /orders
+page.server.ts -- orders load
[id]/
+page.svelte -- /orders/:id
+page.server.ts
api/
orders/
+server.ts -- /api/orders
export const load: PageServerLoad = async ({ locals, url }) => {
return { orders: await db.order.findMany({ where: { userId: locals.user.id } }) }
}
export const actions: Actions = {
default: async ({ request }) => {
const data = await request.formData()
// validate, process
throw redirect(303, '/success')
}
}
export const GET: RequestHandler = async () => {
return json(await db.product.findMany())
}
export const handle: Handle = async ({ event, resolve }) => {
event.locals.user = await getUser(event.cookies.get('session'))
return await resolve(event)
}
Hand off to frontend/universal/state-management/SKILL.md or frontend/universal/performance/SKILL.md.
function createModule<T>(config: ModuleConfig): T { const dependencies = initializeDependencies(config); const module = new Module(dependencies); module.hooks.onInit(); return module as T; }
class ConfigBuilder { private config: AppConfig = new AppConfig(); withDatabase(url: string): ConfigBuilder { ... } withCache(ttl: number): ConfigBuilder { ... } withLogging(level: string): ConfigBuilder { ... } build(): AppConfig { return this.config; } }
| Metric | Threshold | Severity | Action |
|---|---|---|---|
| Error rate | > 1% | Critical | Rollback or fix |
| p95 latency | > 500ms | Warning | Profile and optimize |
| Uptime | < 99.9% | Critical | Investigate infrastructure |
| Memory usage | > 80% | Warning | Check for leaks |
| CPU usage | > 80% | Warning | Scale up or optimize |
Does the data change on every request?
├── No → Can it be static at build time?
│ ├── Yes → `export const prerender = true` + PageData build
│ └── No → Is it user-specific?
│ ├── Yes → load() function with fetch() + cookies
│ └── No → load() with `+page.server.ts` for DB access
└── Yes → Should it be cached?
├── Yes → `load()` with `Cache-Control` headers or `+page.server.ts` cached fetch
└── No → `load()` with per-request fresh data
Is the form complex (multi-step, file uploads)?
├── No → Simple form with bind:value + <form> + use:enhance
└── Yes → Does it need optimistic updates?
├── Yes → use:enhance with custom callback for optimistic UI
└── No → +page.server.ts with form actions (default, login, register)
Need file uploads?
├── Yes → multipart/form-data + server action + file validation
└── No → JSON-based form data via FormData