17.2 환경 설정
Svelte 개발 환경을 구축하는 방법은 크게 두 가지입니다. SvelteKit(풀스택 프레임워크)을 사용하거나, 순수 Svelte + Vite 조합을 사용합니다. 대부분의 실제 프로젝트에서는 SvelteKit을 권장합니다.
사전 요구사항
# Node.js 버전 확인 (18+ 필요)
node --version # v18.x.x 이상
# npm 버전 확인
npm --version # 8+ 권장
# VS Code 확장 설치
# "Svelte for VS Code" (svelte.svelte-vscode)
방법 1: SvelteKit으로 프로젝트 생성 (권장)
SvelteKit은 Svelte의 공식 애플리케이션 프레임워크입니다. 라우팅, SSR, SSG, API 엔드포인트 등을 모두 지원합니다.
# SvelteKit 프로젝트 생성
npm create svelte@latest my-svelte-app
# 대화형 프롬프트
# ┌ Welcome to SvelteKit!
# │
# ◆ Which Svelte app template?
# │ ○ SvelteKit demo app
# │ ● Skeleton project ← 권장
# │ ○ Library project
# │
# ◆ Add type checking with TypeScript?
# │ ○ Yes, using TypeScript syntax
# │ ● Yes, using JavaScript with JSDoc comments ← JS 선택 시
# │ ○ No
# │
# ◆ Select additional options
# │ ☑ Add ESLint for code linting
# │ ☑ Add Prettier for code formatting
# │ ☑ Add Playwright for browser testing
# │ ☑ Add Vitest for unit testing
cd my-svelte-app
npm install
npm run dev
개발 서버 실행
npm run dev # 개발 서버 (localhost:5173)
npm run dev -- --open # 브라우저 자동 오픈
npm run build # 프로덕션 빌드
npm run preview # 빌드 결과물 미리보기
방법 2: 순수 Svelte + Vite
SvelteKit 없이 단순 SPA(Single Page Application)가 필요할 때 사용합니다.
# Vite 템플릿으로 Svelte 프로젝트 생성
npm create vite@latest my-svelte-app -- --template svelte
# TypeScript 버전
npm create vite@latest my-svelte-app -- --template svelte-ts
cd my-svelte-app
npm install
npm run dev
프로젝트 디렉토리 구조 (SvelteKit)
my-svelte-app/
├── src/
│ ├── app.html # HTML 진입점 (기본 HTML 쉘)
│ ├── app.css # 전역 CSS
│ ├── lib/ # 재사용 가능한 코드 ($lib 별칭)
│ │ ├── components/ # 공유 컴포넌트
│ │ ├── stores/ # Svelte 스토어
│ │ └── utils/ # 유틸리티 함수
│ └── routes/ # 파일 기반 라우팅
│ ├── +layout.svelte # 루트 레이아웃
│ ├── +page.svelte # / 경로 페이지
│ └── about/
│ └── +page.svelte # /about 경로 페이지
├── static/ # 정적 파일 (이미지, 폰트 등)
├── tests/ # 테스트 파일
├── svelte.config.js # Svelte/SvelteKit 설정
├── vite.config.js # Vite 설정
└── package.json
src/app.html
<!doctype html>
<html lang="ko">
<head>
<meta charset="utf-8" />
<link rel="icon" href="%sveltekit.assets%/favicon.png" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
%sveltekit.head%
</head>
<body data-sveltekit-preload-data="hover">
<div style="display: contents">%sveltekit.body%</div>
</body>
</html>
%sveltekit.head%: SvelteKit이 주입하는 head 내용 (title, meta, link 등)%sveltekit.body%: 실제 페이지 내용%sveltekit.assets%: 정적 에셋 경로
svelte.config.js 주요 설정
// svelte.config.js
import adapter from '@sveltejs/adapter-auto';
import { vitePreprocess } from '@sveltejs/vite-plugin-svelte';
/** @type {import('@sveltejs/kit').Config} */
const config = {
// 전처리기 설정 (TypeScript, SCSS 등)
preprocess: vitePreprocess(),
kit: {
// 어댑터 설정 (배포 환경에 따라 변경)
adapter: adapter(),
// 경로 별칭 설정
alias: {
$lib: 'src/lib',
$components: 'src/lib/components',
$stores: 'src/lib/stores',
},
// CSRF 보호 설정
csrf: {
checkOrigin: true,
},
// 환경 변수 접두사
env: {
publicPrefix: 'PUBLIC_',
},
},
// Svelte 컴파일러 옵션
compilerOptions: {
// Runes 모드 전역 활성화 (Svelte 5)
// runes: true, // 주석 해제하면 모든 파일에 Runes 적용
},
};
export default config;
TypeScript 설정
TypeScript를 사용하는 경우 tsconfig.json이 자동 생성됩니다:
// tsconfig.json
{
"extends": "./.svelte-kit/tsconfig.json",
"compilerOptions": {
"allowJs": true,
"checkJs": true,
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"resolveJsonModule": true,
"skipLibCheck": true,
"sourceMap": true,
"strict": true
}
}
TypeScript Svelte 컴포넌트
<!-- Counter.svelte -->
<script lang="ts">
interface Props {
initialCount?: number;
label?: string;
}
let { initialCount = 0, label = '카운터' }: Props = $props();
let count = $state(initialCount);
function increment(): void {
count++;
}
function reset(): void {
count = initialCount;
}
</script>
<div>
<h2>{label}: {count}</h2>
<button onclick={increment}>+1</button>
<button onclick={reset}>초기화</button>
</div>
Vite 설정
// vite.config.js
import { sveltekit } from '@sveltejs/kit/vite';
import { defineConfig } from 'vite';
export default defineConfig({
plugins: [sveltekit()],
// 개발 서버 설정
server: {
port: 5173,
open: true,
},
// 빌드 최적화
build: {
target: 'es2020',
sourcemap: true,
},
// 테스트 설정 (Vitest)
test: {
include: ['src/**/*.{test,spec}.{js,ts}'],
environment: 'jsdom',
globals: true,
setupFiles: ['./src/setupTests.ts'],
},
});
VS Code 확장 및 설정
필수 확장
- Svelte for VS Code (
svelte.svelte-vscode): 문법 강조, 자동완성, 타입 체크 - ESLint (
dbaeumer.vscode-eslint): 코드 품질 검사 - Prettier (
esbenp.prettier-vscode): 코드 포맷팅
.vscode/settings.json
{
"editor.formatOnSave": true,
"editor.defaultFormatter": "esbenp.prettier-vscode",
"[svelte]": {
"editor.defaultFormatter": "svelte.svelte-vscode"
},
"svelte.enable-ts-plugin": true,
"typescript.preferences.importModuleSpecifier": "shortest"
}
.prettierrc
{
"semi": true,
"singleQuote": true,
"tabWidth": 2,
"trailingComma": "es5",
"plugins": ["prettier-plugin-svelte"],
"overrides": [
{
"files": "*.svelte",
"options": {
"parser": "svelte"
}
}
]
}
어댑터 개념 소개
SvelteKit은 **어댑터(Adapter)**를 통해 다양한 플랫폼에 배포합니다. 어댑터는 빌드 결과물을 특정 배포 환경에 맞게 변환합니다.
| 어댑터 | 패키지 | 용도 |
|---|---|---|
adapter-auto | @sveltejs/adapter-auto | 플랫폼 자동 감지 (기본값) |
adapter-node | @sveltejs/adapter-node | Node.js 서버 |
adapter-static | @sveltejs/adapter-static | 정적 사이트 (SSG) |
adapter-cloudflare | @sveltejs/adapter-cloudflare | Cloudflare Pages |
adapter-vercel | @sveltejs/adapter-vercel | Vercel |
adapter-netlify | @sveltejs/adapter-netlify | Netlify |
// svelte.config.js - 정적 사이트 어댑터 예시
import adapter from '@sveltejs/adapter-static';
export default {
kit: {
adapter: adapter({
pages: 'build',
assets: 'build',
fallback: '404.html',
precompress: false,
strict: true,
}),
prerender: {
handleHttpError: 'warn',
},
},
};
첫 번째 컴포넌트 만들기
프로젝트 생성 후 첫 페이지를 수정해 보겠습니다:
<!-- src/routes/+page.svelte -->
<script>
import Counter from '$lib/Counter.svelte';
</script>
<main>
<h1>나의 첫 Svelte 앱</h1>
<Counter initialCount={5} label="방문 횟수" />
</main>
<style>
main {
max-width: 800px;
margin: 0 auto;
padding: 2rem;
text-align: center;
}
</style>
<!-- src/lib/Counter.svelte -->
<script>
let { initialCount = 0, label = '카운터' } = $props();
let count = $state(initialCount);
</script>
<div class="counter">
<p>{label}: <strong>{count}</strong></p>
<button onclick={() => count--}>-</button>
<button onclick={() => count++}>+</button>
</div>
<style>
.counter {
display: inline-flex;
align-items: center;
gap: 1rem;
padding: 1rem 2rem;
border: 2px solid #ff3e00;
border-radius: 8px;
}
button {
width: 36px;
height: 36px;
background: #ff3e00;
color: white;
border: none;
border-radius: 50%;
font-size: 1.2rem;
cursor: pointer;
}
</style>
개발 명령어 정리
npm run dev # 개발 서버 시작
npm run build # 프로덕션 빌드
npm run preview # 빌드 미리보기
npm run check # TypeScript + Svelte 타입 체크
npm run lint # ESLint 실행
npm run format # Prettier 포맷팅
npm run test # Vitest 단위 테스트
npm run test:e2e # Playwright E2E 테스트
고수 팁
팁 1: 환경 변수 관리
# .env 파일
DATABASE_URL=postgresql://... # 서버 전용 (노출 안 됨)
PUBLIC_API_URL=https://api.example.com # 클라이언트 노출 가능
<script>
import { PUBLIC_API_URL } from '$env/static/public';
import { DATABASE_URL } from '$env/static/private'; // 서버 컴포넌트에서만
</script>
팁 2: 경로 별칭 활용
<!-- 상대 경로 대신 별칭 사용 -->
<script>
// 비권장
import Button from '../../../lib/components/Button.svelte';
// 권장
import Button from '$lib/components/Button.svelte';
</script>
팁 3: SvelteKit Inspector
개발 모드에서 컴포넌트를 클릭하면 해당 소스 파일로 바로 이동하는 기능:
# 환경 변수 설정
SVELTE_INSPECTOR=true npm run dev
또는 svelte.config.js에서 설정:
import { vitePreprocess } from '@sveltejs/vite-plugin-svelte';
export default {
preprocess: vitePreprocess(),
vitePlugin: {
inspector: {
holdMode: true, // 특정 키를 누를 때만 활성화
},
},
};
정리
| 도구 | 역할 |
|---|---|
| SvelteKit | 라우팅, SSR, API, 풀스택 지원 |
| Vite | 번들러, 개발 서버, HMR |
svelte.config.js | Svelte 컴파일러 및 SvelteKit 설정 |
vite.config.js | Vite 빌드 설정 |
| Adapter | 배포 플랫폼 대응 |
$lib 별칭 | src/lib 경로 단축 |
다음 장에서는 Svelte 5의 핵심인 반응성 원리와 Runes 시스템을 자세히 살펴봅니다.