Communitygithub.com

agentmemoir/skills

정적(서버 없음) Svelte 5 앱을 runes($state, $derived, $effect, $props, $bindable)를 사용하여 빌드, 마이그레이션 또는 리뷰합니다. 레거시 Svelte 4 반응성(export let, reactive $: 문, stores-as-default) 대신 사용합니다.

skills란 무엇인가요?

이 스킬은 개발자가 Svelte 5의 runes 기반 반응성을 사용하여 정적(서버리스) Svelte 애플리케이션을 구축, 마이그레이션 또는 검토할 수 있도록 안내합니다. Svelte 5 자체는 서버 구성 요소를 지원하지만, 이 스킬은 GitHub Pages, Netlify 또는 Cloudflare Pages와 같은 정적 호스팅에 배포하기 위해 '서버가 없는' 최종 결과물에 중점을 둡니다. Svelte 4의 `export let`, `$:` 및 writable 스토어와 같은 레거시 패턴을 식별하고, 이를 runes(`$state`, `$derived`, `$effect`, `$props`, `$bindable`)를 사용하는 Svelte 5의 최신 방식으로 변환하는 방법에 대한 명확한 지침을 제공합니다. 이 스킬은 또한 XSS 방지, 실수로 인한 비밀 노출 방지, Content-Security-Policy 적용과 같은 정적 사이트의 중요한 보안 측면을 강조합니다. 특히 정적 사이트에서는 이를 적용할 서버 측 레이어가 없으므로 클라이언트 측 보안은 전적으로 개발자에게 달려 있기 때문입니다. 이 스킬은 여러 참조 파일(`references/runes.md`, `references/static-build.md`, `references/security.md`)을 포함하며, 도구가 적절한 구성을 생성하고 오류를 방지하는 데 사용합니다. 일반적인 SvelteKit 앱을 `adapter-static`으로 전환할 때 발생하는 함정(예: 서버 전용 파일이나 로컬 개발 환경에서만 작동하는 코드)을 식별하는 데 특히 유용하며, svelte.config.js, vite.config.js 및 XSS 방지를 위한 DOMPurify 래퍼와 같은 템플릿 파일도 제공합니다.

지원 대상~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/agentmemoir/skills/tree/HEAD/skills/frontend/svelte5-static-runes

즐겨 사용하는 AI에게 물어보기

이 에이전트 스킬이 미리 로드된 새 채팅을 엽니다.

문서

Svelte 5 정적 전용 (Runes)

이 스킬이 다루는 내용

"정적 전용"이란 결과물이 사전 구축된 HTML/CSS/JS 폴더이며 요청 시 Node/에지 서버가 없는 것을 의미합니다. GitHub Pages, Netlify/Cloudflare/Vercel 정적 호스팅, S3+CloudFront에서 호스팅하거나 로컬 파일로 열 수 있습니다. 이러한 제약은 +page.server.js, +server.js, 폼 액션, hooks.server.js 및 실행 중인 서버를 가정하는 모든 코드 경로를 배제합니다. "Runes"는 구성 요소 반응성이 Svelte 5의 $state/$derived/$effect/$props 프리미티브로 작성되었음을 의미하며, Svelte 4의 export let / $: / 암시적 반응성이 아닙니다.

이 두 가지 제약은 상호 작용합니다. 정적 빌드는 $effect 내부를 포함하여 어떤 코드도 요청별로 서버에서 실행된다고 가정하지 않는 경우에만 깔끔하게 작동합니다. 이 점을 항상 염두에 두십시오. 사람들이 SvelteKit 앱을 adapter-static으로 이동할 때 대부분의 버그가 발생하는 원천입니다.

1단계 — 올바른 프로젝트 형태 선택

앱에 파일 기반 라우팅, 여러 개의 사전 렌더링된 페이지 또는 SEO 친화적인 경로별 HTML이 필요한지 질문(또는 컨텍스트에서 추론)하십시오. 이는 전체 설정을 결정하므로 건너뛰지 마십시오.

필요 사항사용 방법
단일 페이지 / 대시보드 / 위젯 / 임베드, 라우팅 불필요일반 Vite + Svelte (npm create vite@latest -- --template svelte-ts). 실수로 서버를 도입할 위험이 없는 가장 간단한 정적 전용 설정입니다.
여러 경로, 각각 자체 HTML 파일로 사전 렌더링됨, SEO 중요prerender = true 가 설정된 SvelteKit + @sveltejs/adapter-static
여러 경로지만 SEO는 중요하지 않음 (내부 도구, Chrome 확장 프로그램, Electron/Tauri UI)SPA 모드의 SvelteKit + adapter-static (단일 fallback: 'index.html' 셸, 클라이언트 측 라우팅)

특별히 라우팅이 필요하지 않다면 기본적으로 일반 Vite+Svelte를 사용하십시오. 설정이 덜 복잡하고 잘못 구성할 위험이 적습니다. 두 경로에 대한 전체 설정 단계, 구성 파일 및 배포 노트는 references/static-build.md에 있습니다. svelte.config.js / vite.config.js를 메모리에서 생성하기 전에 읽으십시오. prerender/adapter 옵션은 Svelte 버전에 따라 변경되며 미묘하게 잘못 설정하기 쉽습니다(예: trailingSlash를 잊거나, 사전 렌더링하려는 페이지에서 ssr = false를 설정하여 실제 HTML 대신 빈 셸을 생성하는 경우).

2단계 — Svelte 4 구문 대신 runes로 구성 요소 작성

새로운 Svelte 5 코드에서 export let, $:, on:click 또는 일반 writable() 스토어를 구성 요소 상태를 관리하는 주요 방식으로 절대 작성하지 마십시오. 이러한 구문은 대부분의 구성에서 여전히 컴파일되지만 레거시 패턴입니다. 여기서 요구하는 것은 runes입니다. 핵심 매핑:

Svelte 4Svelte 5
let count = 0 (최상위 수준이므로 반응적)let count = $state(0)
$: doubled = count * 2let doubled = $derived(count * 2) (또는 다중 문 로직의 경우 $derived.by(() => ...))
$: { sideEffect(count) }$effect(() => { sideEffect(count) })
export let namelet { name } = $props()
export let value; bind:value (자식 변경)let { value = $bindable() } = $props()
DOM 전용 설정/해제를 위한 onMount/onDestroy$effect(() => { ...; return () => cleanup(); })
<slot name="header">{#snippet header()}...{/snippet} + {@render header()}
writable()/readable() 스토어, 구성 요소 내 $store.svelte.js/.svelte.ts 모듈의 $state(...), 직접 가져오기 (반응성이 이제 구성 요소 외부에서도 작동)

중요하지 않은 rune 코드를 작성하기 전에 references/runes.md를 읽으십시오. 사람들이 확실히 틀리는 부분을 다룹니다: $derived는 순수해야 함(내부에 부작용이나 상태 변이 없음), $effect는 읽는 동일한 상태에 절대 쓰면 안 됨(무한 루프), 재할당하는 대규모/동결 데이터를 위한 $state.raw, 구성 요소 수명 주기 외부에서 공유되는 상태를 위한 $effect.root/untrack, 그리고 구성 요소 간/모듈 상태를 위한 정확한 클래스 기반 패턴. 이러한 부분을 잘못 이해하면 이상한 재렌더링 루프나 오래된 UI로만 나타나는 버그가 발생하므로 나중에 진단하기 어렵습니다. 처음부터 올바르게 작성하는 것이 좋습니다.

기존 Svelte 4 코드를 마이그레이션할 때 npx sv migrate svelte-5는 기계적인 재작성을 처리합니다(현재 도구입니다. 오래된 문서는 svelte-migrate를 참조할 수 있음). 그러나 항상 diff를 검토하십시오. 자동화된 마이그레이션은 교차 모듈 상태 패턴으로서의 스토어나 파생된 값이어야 하는 효과를 안정적으로 수정하지 못합니다.

3단계 — 보안 체크리스트 적용

정적 호스팅이 "보안 표면이 없다"는 의미는 아닙니다. 서버 측 공격 벡터는 제거되지만 클라이언트 측 공격 벡터(XSS, 비밀 누출, 안전하지 않은 타사 임베드)는 이를 차단할 서버 측 레이어가 없으므로 전적으로 개발자에게 달려 있습니다. 사용자 생성 콘텐츠, {@html}, 환경 변수 또는 타사 스크립트를 다루는 작업을 완료하기 전에 references/security.md를 확인하십시오. 빠른 작업에서도 놓치지 않도록 가장 영향력이 큰 규칙:

  1. 비위생 콘텐츠를 {@html}에 전달하지 마십시오. Svelte는 {expression} 중괄호 안의 모든 것을 자동으로 이스케이프 처리하지만 {@html ...}는 이를 완전히 우회합니다. 이는 Svelte 앱에서 가장 큰 XSS 원천입니다. DOMPurify(또는 엄격한 허용 목록)를 사용하여 렌더링 직전에 즉시 위생 처리하고, 파이프라인 초기 단계에서 처리하지 마십시오. 나중에 편집으로 인해 우회될 수 있습니다.
  2. VITE_ 접두사(또는 SvelteKit PUBLIC_ 접두사)가 붙은 환경 변수 뒤에 실제 비밀을 절대 두지 마십시오. Vite는 이를 빌드 시 출하된 JS 번들에 인라인 처리합니다. 누구나 빌드된 파일에서 읽을 수 있습니다. 정적 전용 앱에는 비밀을 숨길 서버가 전혀 없습니다. 따라서 앱에 실제 API 키가 필요한 경우 키는 타사 서비스의 서버에 있거나 별도로 배포한 서버리스 함수/프록시 뒤에 있어야 합니다. 조용히 키를 클라이언트 코드에 연결하지 말고 이 점을 알려주십시오.
  3. 서버에서 헤더를 보낼 수 없더라도 Content-Security-Policy를 설정하십시오. 정적 호스트는 app.html/index.html의 <meta http-equiv="Content-Security-Policy"> 태그 또는 호스트별 헤더 파일(Netlify _headers, Cloudflare Pages _headers, Vercel vercel.json headers)을 통해 이를 계속 지원합니다. 자세한 내용은 references/security.md를 참조하십시오.
  4. 모든 동적 href/src가 사용자 입력 또는 API 응답에서 올 수 있다면 공격자에 의해 제어된다고 간주하십시오. Svelte는 href 바인딩에서 javascript: URL을 차단하지 않습니다. 직접 체계를 검증/허용 목록에 추가하십시오.
  5. 출시 전에 npm audit(또는 이에 상응하는 도구)를 실행하고 잠금 파일을 고정하십시오. 정적 사이트는 모든 종속성의 코드를 브라우저로 직접 전달하므로 손상된 종속성은 직접적인 클라이언트 측 손상입니다.

참조 파일

  • references/runes.md — 올바른/잘못된 패턴, 클래스 기반 공유 상태, props/snippets용 TypeScript 타이핑 및 Svelte 4에서 5로의 마이그레이션 테이블을 상세히 다루는 전체 rune별 가이드.
  • references/static-build.md — 일반 Vite+Svelte 설정, SvelteKit+adapter-static 설정(전체 사전 렌더링 및 SPA 폴백 모드), trailing-slash/base-path 문제 및 호스트별 배포 노트(GitHub Pages, Netlify, Cloudflare Pages, S3/CloudFront).
  • references/security.md — 전체 체크리스트: XSS/{@html}/DOMPurify, 정적 호스트용 CSP(메타 태그 + _headers 템플릿), 비밀/환경 변수, 안전한 외부 링크, 종속성 감사, Trusted Types, localStorage/sessionStorage 민감성 및 출시 전 체크리스트.
  • assets/ — 복사 가능한 시작 파일: vite.config.ts, svelte.config.js(adapter-static), _headers(CSP 템플릿) 및 SecureHtml.svelte(DOMPurify 래퍼 구성 요소).

내용을 메모리에서 재현하기보다 필요에 따라 이러한 파일을 가져오십시오. 구성 옵션 이름과 CSP 지시문 세부 사항은 정확히 시간이 지나면서 구식이 되거나 잘못 기억되기 쉬운 종류의 세부 정보입니다.

Individual skills in this repo

This repo contains 2 individual skills — each has its own dedicated page.

관련 스킬