Svelte + Electron — 경량 프레임워크로 가벼운 앱 만들기
"Svelte는 번들 크기가 작아 Electron의 메모리 사용량 단점을 조금이라도 줄일 수 있는 선택" — 가상 DOM 없이 컴파일 시점에 최적화되는 Svelte의 특성이 Electron과 잘 맞습니다.
프로젝트 설정
electron-vite + Svelte
npm create @quick-start/electron my-svelte-app -- --template svelte-ts
cd my-svelte-app
npm install
npm run dev
프로젝트 구조
my-svelte-app/
├── src/
│ ├── main/
│ │ └── index.ts
│ ├── preload/
│ │ └── index.ts
│ └── renderer/
│ ├── src/
│ │ ├── App.svelte
│ │ └── main.ts
│ └── index.html
├── electron.vite.config.ts
└── package.json
Svelte 컴포넌트에서 Electron API 사용
<!-- renderer/src/App.svelte -->
<script lang="ts">
import { onMount, onDestroy } from 'svelte';
let content = '';
let filePath: string | null = null;
let version = '';
let cleanup: (() => void) | null = null;
onMount(async () => {
version = await window.electronAPI.getVersion();
// 메인 프로세스 이벤트 수신
cleanup = window.electronAPI.onMenuAction((action: string) => {
if (action === 'save') handleSave();
if (action === 'open') handleOpen();
});
});
onDestroy(() => {
cleanup?.();
});
async function handleOpen() {
const path = await window.electronAPI.openFile();
if (path) {
filePath = path;
}
}
async function handleSave() {
if (content) {
await window.electronAPI.saveFile(content);
}
}
</script>
<main>
<div class="toolbar">
<button on:click={handleOpen}>열기</button>
<button on:click={handleSave}>저장</button>
{#if filePath}
<span class="filepath">{filePath}</span>
{/if}
</div>
<textarea bind:value={content} placeholder="내용을 입력하세요..." />
<footer>Electron v{version}</footer>
</main>
<style>
main {
display: flex;
flex-direction: column;
height: 100vh;
}
textarea {
flex: 1;
padding: 1rem;
border: none;
resize: none;
font-family: monospace;
}
</style>
Svelte Store로 Electron 상태 관리
// renderer/src/stores/electron.ts
import { writable, derived } from 'svelte/store';
// 앱 설정 스토어
function createSettingsStore() {
const { subscribe, set, update } = writable({
theme: 'light' as 'light' | 'dark',
fontSize: 14,
autoSave: true,
});
return {
subscribe,
async load() {
const settings = await window.electronAPI.getSettings();
set(settings);
},
async setTheme(theme: 'light' | 'dark') {
update(s => ({ ...s, theme }));
await window.electronAPI.setSetting('theme', theme);
},
async setFontSize(size: number) {
update(s => ({ ...s, fontSize: size }));
await window.electronAPI.setSetting('fontSize', size);
},
};
}
export const settings = createSettingsStore();
<!-- 컴포넌트에서 사용 -->
<script lang="ts">
import { settings } from '../stores/electron';
import { onMount } from 'svelte';
onMount(() => settings.load());
</script>
<div style="font-size: {$settings.fontSize}px">
<select
value={$settings.theme}
on:change={(e) => settings.setTheme(e.currentTarget.value)}
>
<option value="light">라이트</option>
<option value="dark">다크</option>
</select>
</div>
React, Vue와의 비교
| 항목 | React | Vue | Svelte |
|---|---|---|---|
| 번들 크기 | 크다 | 보통 | 작다 |
| 런타임 오버헤드 | 가상 DOM | 가상 DOM | 없음 (컴파일) |
| 생태계 | 가장 크다 | 크다 | 성장 중 |
| 학습 곡선 | 보통 | 낮음 | 낮음 |
| Electron 호환성 | 좋음 | 좋음 | 좋음 |
Svelte는 번들 크기가 작고 런타임 오버헤드가 없어서 Electron 앱의 메모리 사용량을 줄이는 데 유리합니다.
면접 포인트 정리
- Svelte는 컴파일 타임 최적화로 번들이 작고 런타임 오버헤드가 없음
onMount/onDestroy로 Electron 이벤트 리스너 생명주기 관리- Svelte Store로 Electron 설정을 반응형으로 관리 가능
- 앱 성능이 중요하다면 Svelte가 좋은 선택
Svelte 통합까지 살펴봤으면, 다음은 Electron Forge와 Electron Builder의 차이를 비교해봅시다.
댓글 로딩 중...