Skip to content
Back to Blog
#sveltekit #튜토리얼 #웹개발 #javascript

SvelteKit 시작하기 - 현대적인 웹 프레임워크 완벽 가이드

5 min read

SvelteKit의 기초부터 실전 배포까지 완벽하게 마스터하세요. 프로젝트 설정, 라우팅, 데이터 로딩, API 엔드포인트 구축, SSR/SSG 최적화 기법을 실습 중심으로 설명합니다. 초보자도 따라 할 수 있는 단계별 튜토리얼로 현대적인 웹 애플리케이션 개발을 시작해보세요.

📋 핵심 내용 요약

  • 현대적 프레임워크: Svelte 기반의 공식 풀스택 애플리케이션 프레임워크
  • 파일 기반 라우팅: 직관적인 디렉토리 구조로 라우트 자동 생성
  • 뛰어난 성능: 가상 DOM 없이 빠른 실행 속도와 작은 번들 크기
  • 유연한 배포: SPA, MPA, SSR, SSG 모두 지원 + 다양한 어댑터
  • 개발 경험: 간결한 코드 + TypeScript 완벽 지원 + 핫 모듈 리로딩

🤖 AI 요약

SvelteKit은 Svelte 팀이 만든 차세대 웹 애플리케이션 프레임워크로, React의 Next.js나 Vue의 Nuxt와 유사하지만 더 나은 성능과 개발 경험을 제공합니다.

왜 SvelteKit인가? 가상 DOM을 사용하지 않아 더 빠른 실행 속도작은 번들 크기를 자랑합니다. 컴파일 타임에 최적화된 순수 JavaScript로 변환되므로 런타임 오버헤드가 거의 없습니다. 코드도 훨씬 간결하고 읽기 쉽습니다.

파일 기반 라우팅: src/routes/ 디렉토리 구조가 곧 URL 구조입니다. +page.svelte로 페이지를, +layout.svelte로 공통 레이아웃을, +server.ts로 API 엔드포인트를 만들 수 있습니다. 대괄호 [slug]를 사용하면 동적 라우트도 쉽게 구현됩니다.

데이터 로딩: +page.ts(Universal Load)는 클라이언트/서버 양쪽에서, +page.server.ts(Server Load)는 서버에서만 실행됩니다. 민감한 데이터는 Server Load에서 처리하여 보안을 유지할 수 있습니다.

유연한 배포: 다양한 어댑터로 어디든 배포 가능합니다 - Vercel, Netlify, Cloudflare Pages, Node.js 서버, 또는 완전한 정적 사이트로 빌드할 수 있습니다. SPA, MPA, SSR, SSG 모두 지원하므로 프로젝트 요구사항에 맞게 선택할 수 있습니다.

개발 경험: TypeScript 완벽 지원, 핫 모듈 리로딩, Tailwind CSS 통합, 그리고 Vite 기반의 빠른 개발 서버까지 - 모든 것이 현대적인 개발 경험을 위해 최적화되어 있습니다.


SvelteKit은 현대적인 웹 애플리케이션을 구축하기 위한 강력한 프레임워크입니다. 이 글에서는 SvelteKit의 기초부터 실전 활용까지 단계별로 알아보겠습니다.

SvelteKit이란?

SvelteKit은 Svelte 팀이 만든 공식 애플리케이션 프레임워크로, 다음과 같은 기능을 제공합니다:

  • 📁 파일 기반 라우팅: 직관적인 디렉토리 구조로 라우트 관리
  • ⚡ 서버 사이드 렌더링: 빠른 초기 페이지 로딩
  • 🏗️ 정적 사이트 생성: 어디든 배포 가능
  • 🔌 API 라우트: 프론트엔드와 백엔드를 함께 구축
  • 🔥 핫 모듈 리로딩: 개발 중 즉각적인 피드백

왜 SvelteKit인가?

다른 프레임워크와 비교했을 때 SvelteKit의 장점:

1. 성능

  • 가상 DOM이 없어 빠른 실행 속도
  • 최소한의 JavaScript 번들 크기
  • 최적화된 빌드 출력

2. 개발 경험

  • 간결하고 읽기 쉬운 코드
  • 반응성이 기본으로 내장
  • TypeScript 완벽 지원

3. 유연성

  • SPA, MPA, SSR, SSG 모두 지원
  • 다양한 어댑터로 어디든 배포
  • 점진적 개선 가능

사전 준비사항

시작하기 전에 다음을 준비하세요:

  • Node.js (버전 18 이상)
  • 코드 에디터 (VS Code 추천)
  • 기본 지식: JavaScript, HTML, CSS

새 프로젝트 만들기

SvelteKit 프로젝트를 생성하는 방법:

# 프로젝트 생성
npm create svelte@latest my-app

# 프로젝트 디렉토리로 이동
cd my-app

# 의존성 설치
npm install

# 개발 서버 시작
npm run dev

설치 과정에서 다음을 선택하게 됩니다:

  • 프로젝트 템플릿: Skeleton project (기본) 또는 SvelteKit demo app
  • TypeScript 사용 여부: Yes (강력 추천!)
  • ESLint, Prettier: Yes (코드 품질 도구)
  • Playwright: Yes (E2E 테스팅)
  • Vitest: Yes (단위 테스트)

프로젝트 구조

생성된 프로젝트의 구조를 이해해봅시다:

my-app/
├── src/
│   ├── routes/              # 페이지 및 라우트
│   │   ├── +page.svelte    # 홈페이지
│   │   ├── +layout.svelte  # 공통 레이아웃
│   │   └── +error.svelte   # 에러 페이지
│   ├── lib/                 # 공유 컴포넌트 및 유틸
│   │   ├── components/     # UI 컴포넌트
│   │   └── utils/          # 헬퍼 함수
│   └── app.html            # HTML 템플릿
├── static/                  # 정적 파일 (이미지, favicon 등)
├── svelte.config.js        # SvelteKit 설정
├── vite.config.ts          # Vite 설정
└── package.json            # 프로젝트 의존성

주요 디렉토리 설명

src/routes/

  • 모든 페이지와 API 엔드포인트가 위치
  • 디렉토리 구조가 곧 URL 구조

src/lib/

  • 재사용 가능한 컴포넌트와 유틸리티
  • $lib로 간편하게 임포트 가능

static/

  • 이미지, 폰트, favicon 등 정적 파일
  • 빌드 시 그대로 복사됨

라우팅 시스템

SvelteKit의 파일 기반 라우팅은 매우 직관적입니다.

기본 라우트

src/routes/+page.svelte           →  /
src/routes/about/+page.svelte     →  /about
src/routes/blog/+page.svelte      →  /blog
src/routes/contact/+page.svelte   →  /contact

동적 라우트

대괄호를 사용해 동적 파라미터를 만들 수 있습니다:

// src/routes/blog/[slug]/+page.ts
import { error } from '@sveltejs/kit';
import type { PageLoad } from './$types';

export const load: PageLoad = async ({ params }) => {
  const post = await getPost(params.slug);

  if (!post) {
    throw error(404, 'Post not found');
  }

  return { post };
};
<!-- src/routes/blog/[slug]/+page.svelte -->
<script lang="ts">export let data;
</script>

<article>
  <h1>{data.post.title}</h1>
  <time>{data.post.date}</time>
  <div class="prose">
    {@html data.post.content}
  </div>
</article>

<style>
  article {
    max-width: 800px;
    margin: 0 auto;
    padding: 2rem;
  }
</style>

중첩 라우트와 레이아웃

<!-- src/routes/blog/+layout.svelte -->
<script lang="ts">import BlogSidebar from "$lib/components/BlogSidebar.svelte";
</script>

<div class="blog-layout">
  <aside>
    <BlogSidebar />
  </aside>
  <main>
    <slot /> <!-- 자식 페이지가 여기에 렌더링 -->
  </main>
</div>

<style>
  .blog-layout {
    display: grid;
    grid-template-columns: 250px 1fr;
    gap: 2rem;
  }
</style>

데이터 로딩

SvelteKit에서 데이터를 로드하는 두 가지 방법:

1. Universal Load (+page.ts)

클라이언트와 서버 모두에서 실행됩니다:

// src/routes/posts/+page.ts
import type { PageLoad } from './$types';

export const load: PageLoad = async ({ fetch }) => {
  const response = await fetch('https://api.example.com/posts');
  const posts = await response.json();

  return {
    posts
  };
};

2. Server Load (+page.server.ts)

서버에서만 실행되며, 민감한 데이터 처리 가능:

// src/routes/dashboard/+page.server.ts
import { redirect } from '@sveltejs/kit';
import type { PageServerLoad } from './$types';

export const load: PageServerLoad = async ({ locals, cookies }) => {
  // 인증 확인
  if (!locals.user) {
    throw redirect(307, '/login');
  }

  // 데이터베이스 조회 (서버에서만 실행)
  const userData = await db.getUserData(locals.user.id);

  return {
    user: userData
  };
};

스타일링

SvelteKit은 다양한 스타일링 방식을 지원합니다.

컴포넌트 스코프 CSS

<script lang="ts">let count = 0;
</script>

<button on:click={() => count++}>
  클릭 {count}번
</button>

<style>
  button {
    background: linear-gradient(to right, #667eea, #764ba2);
    color: white;
    padding: 1rem 2rem;
    border: none;
    border-radius: 0.5rem;
    cursor: pointer;
    font-size: 1rem;
    transition: transform 0.2s;
  }

  button:hover {
    transform: scale(1.05);
  }
</style>

Tailwind CSS 통합

이 블로그에서 사용하는 방식입니다:

# Tailwind CSS 4.0 설치
npm install -D tailwindcss@next @tailwindcss/vite@next

# PostCSS 및 Autoprefixer
npm install -D postcss autoprefixer

vite.config.ts 설정:

import { sveltekit } from '@sveltejs/kit/vite';
import tailwindcss from '@tailwindcss/vite';
import { defineConfig } from 'vite';

export default defineConfig({
  plugins: [
    sveltekit(),
    tailwindcss()
  ]
});

src/app.css:

@import "tailwindcss";

사용 예:

<div class="max-w-4xl mx-auto px-4 py-12">
  <h1 class="text-4xl font-bold text-gray-900 dark:text-white mb-6">
    안녕하세요!
  </h1>
  <p class="text-lg text-gray-600 dark:text-gray-400">
    Tailwind CSS를 사용한 스타일링
  </p>
</div>

API 라우트 만들기

SvelteKit에서는 API 엔드포인트도 쉽게 만들 수 있습니다:

// src/routes/api/posts/+server.ts
import { json } from '@sveltejs/kit';
import type { RequestHandler } from './$types';

export const GET: RequestHandler = async () => {
  const posts = await db.getPosts();

  return json(posts);
};

export const POST: RequestHandler = async ({ request }) => {
  const data = await request.json();
  const newPost = await db.createPost(data);

  return json(newPost, { status: 201 });
};

배포하기

정적 사이트로 배포 (이 블로그 방식)

# adapter-static 설치
npm install -D @sveltejs/adapter-static

# svelte.config.js 설정
import adapter from '@sveltejs/adapter-static';

export default {
  kit: {
    adapter: adapter({
      pages: 'build',
      assets: 'build',
      fallback: undefined,
      precompress: false,
      strict: true
    })
  }
};

# 빌드 및 프리뷰
npm run build
npm run preview

다양한 플랫폼에 배포

SvelteKit은 다양한 어댑터를 제공합니다:

  • Vercel: @sveltejs/adapter-vercel
  • Netlify: @sveltejs/adapter-netlify
  • Cloudflare Pages: @sveltejs/adapter-cloudflare
  • Node.js: @sveltejs/adapter-node
  • 정적 사이트: @sveltejs/adapter-static

실전 팁과 모범 사례

1. 레이아웃 활용하기

공통 UI 요소는 레이아웃으로 분리:

<!-- src/routes/+layout.svelte -->
<script lang="ts">import Header from "$lib/components/Header.svelte";
import Footer from "$lib/components/Footer.svelte";
</script>

<div class="app">
  <Header />
  <main>
    <slot />
  </main>
  <Footer />
</div>

2. Load 함수 적극 활용

데이터는 항상 load 함수에서 가져오기:

// ✅ 좋은 예
export const load = async () => {
  const data = await fetchData();
  return { data };
};

// ❌ 나쁜 예 - 컴포넌트에서 직접 fetch
// onMount(async () => {
//   data = await fetch(...);
// });

3. 에러 처리

<!-- src/routes/+error.svelte -->
<script lang="ts">import { page } from "$app/stores";
</script>

<div class="error-page">
  <h1>{$page.status}</h1>
  <p>{$page.error?.message}</p>
  <a href="/">홈으로 돌아가기</a>
</div>

4. TypeScript 활용

// src/lib/types.ts
export interface Post {
  slug: string;
  title: string;
  date: string;
  description: string;
  content: string;
  tags: string[];
}

// src/routes/blog/+page.server.ts
import type { PageServerLoad } from './$types';
import type { Post } from '$lib/types';

export const load: PageServerLoad = async () => {
  const posts: Post[] = await getPosts();
  return { posts };
};

5. 이미지 최적화

<picture>
  <source
    srcset="/images/hero.webp"
    type="image/webp"
  >
  <img
    src="/images/hero.jpg"
    alt="Hero image"
    loading="lazy"
    width="800"
    height="600"
  >
</picture>

성능 최적화

Prerendering

정적 페이지는 빌드 시 미리 렌더링:

// src/routes/about/+page.ts
export const prerender = true;

Code Splitting

자동으로 코드가 분할되지만, 필요시 수동 제어:

// 동적 import로 필요할 때만 로드
const HeavyComponent = await import('$lib/components/HeavyComponent.svelte');

디버깅 팁

개발 도구

<script lang="ts">import { dev } from "$app/environment";
$: if (dev) {
  console.log("Current data:", data);
}
</script>

에러 추적

import { handleError } from '@sveltejs/kit';

export const handle = async ({ event, resolve }) => {
  try {
    return await resolve(event);
  } catch (error) {
    console.error('Error:', error);
    throw error;
  }
};

마무리

SvelteKit은 현대적인 웹 애플리케이션을 만들기 위한 최고의 선택 중 하나입니다.

핵심 요점:

  • 📁 직관적인 파일 기반 라우팅
  • ⚡ 뛰어난 성능과 작은 번들 크기
  • 🔧 유연한 배포 옵션
  • 💎 훌륭한 개발 경험
  • 🎨 다양한 스타일링 옵션

이 블로그도 SvelteKit으로 만들어졌습니다! 실제 프로덕션 환경에서 SvelteKit의 강력함을 직접 경험하고 있습니다.

더 알아보기

다음 포스트에서는 SvelteKit의 고급 패턴과 실전 기법을 다뤄보겠습니다. 기대해주세요!

Happy coding! 🚀


질문이나 피드백이 있으신가요?

이 튜토리얼에 대한 질문이나 제안사항이 있다면 언제든 연락주세요!

📧 이메일: [email protected]

이 글 공유하기

💡 LifeTech Hub

삶을 업그레이드하는 기술과 지혜 - 재테크, 개발, AI, IT, 일상생활

Quick Links

Connect

© 2025 LifeTech Hub. Built with 💜 using SvelteKit

Privacy Terms RSS