vue-todo에 이은 3번째 투두 만들기 프로젝트입니다.
해당 포스팅도 vueJS와 동일한 목차로 정리해보고자 합니다.
1. Svelt의 특징을 알아봅니다.
2. Svelt의 기초적인 활용법을 알아봅니다.
3. Svelt를 활용하여 TODO 앱을 제작해봅니다.
4. 타 프레임워크와 차이점을 비교해봅니다.
Svelt는 약 1~2년 전부터 주목을 받았던 프레임워크 컴파일러입니다.
공식 홈페이지
React와 Vue.js와 같은 선언적인 프레임워크와는 달리,
HTML, CSS, JavaScript를 합쳐 런타임에 필요한 코드만 생성하여 작동.
작은 번들 사이즈를 제공하고, 이에따라 초기 렌더링 속도를 비롯한 애니메이션 및 인터랙션 처리가 용이함.
Svelte는 React 및 Vue.js와 비교하여 문법이 단순
(React처럼 JSX 문법 등을 익히지 않아도 됩니다.)
런타임 중 생성되는 가상 DOM을 사용하지 않으면서도 렌더링 성능을 향상시킴
Svelte 프로젝트는 주로 다양한 기능을 제공하는 Svelte/kit를 활용하여 진행됩니다.
Svelte/kit가 제공하는 추가적인 기능은 다음과 같습니다.
+page.svelte
+page.js
+page.svelte
와 함께 SSR 혹은 CSR에서 실행.+page.server.js
+error.svelte
+layout.svelte
+layout.js
, +layout.server.js
+page.svelte
와 +page.js
관계와 유사.+page.js
에서 +page.svelte
가 필요한 데이터를 로드할 수 있음.// +page.js
/** @type {import('./$types').PageLoad} */
export function load({ params }) {
return {
post: {
title: `Title for ${params.slug} goes here`,
content: `Content for ${params.slug} goes here`
}
};
}
// +page.svelte
<script>
/** @type {import('./$types').PageData} */
export let data;
</script>
<h1>{data.post.title}</h1>
<div>{@html data.post.content}</div>
export const prerender = true;
export const ssr = false;
export const csr = false;
<script>
import Item from './item.svelte'
</script>
<Item carryValue = { 12 } >
<Item {carryValue} >
<script>
export let id
</script>
<p> { id } </p>
// App.svelte
<script>
import Item from './components/item.svelte'
function alertSum(x, y) {
alert(x + y)
}
</script>
<Item {alertSum} />
// child.svelte
<script>
export let alertSum
</script>
<button on:click={(_) => alertSum(5,10)} >alert</button>
<script>
import { writable } from 'svelte/store';
const name = writable('John');
function changeName() {
name.set('Jane');
}
</script>
<button on:click={changeName}>Change Name to Jane</button>
<script>
import { readable } from 'svelte/store';
const users = readable([
{ name: 'John', age: 30 },
{ name: 'Jane', age: 25 }
]);
</script>
{#each $users as user}
<p>{user.name} ({user.age})</p>
{/each}
// 값을 기록하는 부분
<script>
import {setContext} from 'svelte'
const setValues = {
a: 1,
b: 2
}
setContext('setKey', setValue)
...
// 값을 받아쓰는 부분
<script>
import { getContext } from 'svelte'
const getValue = getContext('setKey')
</script>
a: { getValue.a }
b: { getValue.b }
src/store/index.ts
import { writable } from 'svelte/store';
export interface TodoType {
id: number;
text: string;
completed: boolean;
}
// 스토어 생성 관련
// 구독 관련 작업도 다 해줌
export const todoData = writable<TodoType[]>([]);
// src/routes/+page.svelte
<script>
import TodoInput from "../component/TodoInput.svelte";
import TodoList from "../component/TodoList.svelte";
import Total from "../component/Total.svelte";
</script>
<section>
<header>TODO</header>
<TodoInput />
<TodoList />
<Total />
</section>
<script lang="ts">
import {todoData} from "../store"
import Barcode from "./Barcode.svelte";
$: completedTodo = $todoData.filter(todo => todo.completed).length;
$: ratio = $todoData.length > 0 ? Number(completedTodo/$todoData.length*100).toFixed(2) : 0;
</script>
<div>
{#each $todoData as todo (todo.id)}
<TodoItem {todo} />
{/each}
</div>
<label>
<input type="checkbox" bind:checked={completed} on:click={(e) => handleCompleteTodo(id)}/>
{text}
</label>
전체코드: 깃허브링크
리액트에서 가장 학습이 많이 필요한 곳인 전역상태 관리가
스벨트에서는 학습할 것(?)이 없습니다.
그냥 Svelte Store와 Context만 활용하면 뚝딱입니다.
리덕스의 복잡한 보일플레이트도 신경쓸 필요가 없습니다.
앵귤려, 뷰에서 언급했던 폼 관리도 매우 쉽습니다.
bind를 활용하여 폼을 매우 쉽게 관리할 수 있습니다.
폼에 붙는 이벤트도 on: 을 활용하면 다양한 처리가 가능합니다.
그리고 요즘에는 어쩌면 필수라고 여겨지는 SSR 관련 지원까지
Svelte(Kit)가 많은 부분을 제공해주고 있습니다.
또한 성능에 관해서는 단순히 투두앱을 만들어 보았기 때문에,
획기적인 성능 개선을 경험해 봤다라고는 못하지만,
적어도 사라지는 프레임워크로 작용하며,
굉장히 적은 번들사이즈를 제공해준 것은 분명합니다.
새로운 프론트엔드 프레임워크를 접할 수록 항상 더 나은 경험을 하고 있는데,
아마도 간결함에 있어서는 최고이지 않을까 싶습니다.
그럼에도 불구하고, 스벨트가 여전히 높은 시장 점유율을 가지지 못하는 것은,
타 프레임워크에 비해 작은 커뮤니티,
아직 보장되지 않은 배포 환경에서의 안정성(?),
FE시장의 리액트 고인물...
정도가 있을 거 같습니다.
스벨트 만세...? 🥹