2. Установка и Vite
Установка Svelte: npm create svelte и Vite 🛠️
Заголовок раздела «Установка Svelte: npm create svelte и Vite 🛠️»Svelte — это компилятор, а не обычный фреймворк. Он преобразует твои компоненты в чистый, оптимизированный JavaScript во время сборки, без runtime-накладных расходов. Результат — молниеносные приложения с минимальным bundle size. 🚀
Сегодня разберём два способа создать Svelte-проект: через официальный SvelteKit (полный фарш — роутинг, SSR, API) и через чистый Vite + Svelte (простой SPA без лишнего). Разберёмся с каждым файлом проекта по очереди!
Два подхода: SvelteKit vs Vite-only 🛣️
Заголовок раздела «Два подхода: SvelteKit vs Vite-only 🛣️»┌──────────────────────────────────────────────────────────────┐│ Выбор подхода │├────────────────────────────────┬─────────────────────────────┤│ npm create svelte@latest │ npm create vite@latest ││ (SvelteKit) │ (Pure Svelte + Vite) │├────────────────────────────────┼─────────────────────────────┤│ ✅ Файловый роутинг │ ✅ Минимальная настройка ││ ✅ SSR / SSG из коробки │ ✅ Идеально для SPA ││ ✅ API routes (+server.ts) │ ✅ Быстрый старт ││ ✅ Адаптеры (Vercel, Netlify) │ ✅ Полный контроль ││ ✅ Load functions │ ✅ Легко понять структуру ││ ❌ Сложнее для первого знак. │ ❌ Нет роутинга ││ ❌ Больше концепций сразу │ ❌ Нет SSR │└────────────────────────────────┴─────────────────────────────┘Правило Яши: начни с Vite-only, чтобы освоить Svelte без лишних концепций. Потом переходи на SvelteKit!
Способ 1: Vite + Svelte (рекомендую для старта) 🚀
Заголовок раздела «Способ 1: Vite + Svelte (рекомендую для старта) 🚀»npm create vite@latest my-svelte-app -- --template svelte-ts
# Переходим в папкуcd my-svelte-app
# Устанавливаем зависимостиnpm install
# Запускаем dev-серверnpm run devВ терминале увидишь что-то вроде:
VITE v5.x.x ready in 300ms
➜ Local: http://localhost:5173/ ➜ Network: use --host to expose ➜ press h + enter to show helpОткрывай http://localhost:5173 — твой первый Svelte-проект уже работает! 🎉
Другие доступные шаблоны Vite
Заголовок раздела «Другие доступные шаблоны Vite»# Без TypeScriptnpm create vite@latest my-app -- --template svelte
# С TypeScript (рекомендуется)npm create vite@latest my-app -- --template svelte-ts
# Посмотреть все шаблоныnpm create vite@latestСпособ 2: SvelteKit (для полноценных приложений) 🏗️
Заголовок раздела «Способ 2: SvelteKit (для полноценных приложений) 🏗️»# Официальный создатор SvelteKit проектовnpm create svelte@latest my-sveltekit-app
# Мастер задаст несколько вопросов:# ┌ Welcome to SvelteKit!# │# ◆ Which Svelte app template?# │ ● SvelteKit demo app# │ ○ Skeleton project ← выбери это для чистого старта# │ ○ Library project# │# ◆ Add type checking with TypeScript?# │ ○ Yes, using JavaScript with JSDoc comments# │ ● Yes, using TypeScript syntax ← рекомендуется# │ ○ 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-sveltekit-appnpm installnpm run devСтруктура проекта: Vite + Svelte 📁
Заголовок раздела «Структура проекта: Vite + Svelte 📁»my-svelte-app/├── public/ # Статические файлы (копируются as-is)│ └── vite.svg├── src/│ ├── lib/ # Переиспользуемые компоненты и утилиты│ │ └── Counter.svelte # Пример компонента из шаблона│ ├── assets/ # Картинки, шрифты (обрабатываются Vite)│ │ └── svelte.svg│ ├── App.svelte # Корневой компонент приложения│ ├── app.css # Глобальные стили│ └── main.ts # Точка входа — монтирует App в DOM├── index.html # HTML-шаблон (Vite обрабатывает его)├── vite.config.ts # Конфигурация Vite├── svelte.config.js # Конфигурация компилятора Svelte├── tsconfig.json # Конфигурация TypeScript├── tsconfig.node.json # TypeScript для Node.js (vite.config.ts)└── package.jsonСтруктура SvelteKit (для сравнения)
Заголовок раздела «Структура SvelteKit (для сравнения)»my-sveltekit-app/├── src/│ ├── lib/ # Импортируется как $lib/...│ │ ├── components/│ │ └── utils/│ ├── routes/ # Файловый роутинг!│ │ ├── +layout.svelte # Общий лэйаут для всех страниц│ │ ├── +page.svelte # Страница /│ │ ├── about/│ │ │ └── +page.svelte # Страница /about│ │ └── blog/│ │ ├── +page.svelte # Страница /blog│ │ ├── +page.server.ts # Load function (серверный код)│ │ └── [slug]/│ │ └── +page.svelte # Страница /blog/:slug│ └── app.html # HTML-шаблон (с %sveltekit.head% и т.д.)├── static/ # Статические файлы├── svelte.config.js└── package.jsonАнатомия .svelte файла 🧬
Заголовок раздела «Анатомия .svelte файла 🧬»Это самая важная часть! .svelte файл — это особый формат, который объединяет три секции в одном файле:
<!-- Секция 1: Логика компонента --><script lang="ts"> import { onMount } from 'svelte'; import ChildComponent from './ChildComponent.svelte';
// Props (в Svelte 5 — через $props()) let { title = 'Default Title', count = $bindable(0) } = $props();
// Локальное состояние (в Svelte 5 — $state()) let name = $state('World'); let items = $state<string[]>([]);
// Вычисляемые значения (в Svelte 5 — $derived()) let greeting = $derived(`Привет, ${name}!`);
// Эффекты (в Svelte 5 — $effect()) $effect(() => { console.log('name изменился:', name); });
// Обычные функции function addItem(item: string): void { items = [...items, item]; }
// Lifecycle onMount(() => { console.log('Компонент смонтирован'); });</script>
<!-- Секция 2: Шаблон (HTML + Svelte синтаксис) --><!-- Нет обёртки вроде <template> или <div> — фрагменты поддерживаются! --><main class="container"> <h1>{greeting}</h1> <p>Title: {title}</p>
{#each items as item, i (item)} <div>{i + 1}. {item}</div> {/each}
<ChildComponent bind:value={name} /></main>
<!-- Секция 3: Стили (SCOPED по умолчанию!) --><style> /* Эти стили применяются ТОЛЬКО к этому компоненту */ /* Svelte добавляет уникальный класс: .container.svelte-abc123 */ .container { max-width: 800px; margin: 0 auto; padding: 2rem; }
h1 { color: #ff3e00; /* Svelte orange! */ }
/* :global() — если нужно глобально */ :global(body) { margin: 0; }</style>Секция <script context="module"> — запускается один раз
Заголовок раздела «Секция <script context="module"> — запускается один раз»<!-- Запускается при ИМПОРТЕ модуля, не при создании компонента --><!-- Shared между всеми экземплярами компонента --><script context="module"> // Здесь можно экспортировать функции и переменные export const componentVersion = '1.0.0';
// Загрузка данных до рендера (паттерн SvelteKit) export async function load({ fetch }) { const response = await fetch('/api/data'); return { data: await response.json() }; }</script>
<script lang="ts"> // Обычный скрипт компонента let count = $state(0);</script>Почему стили scoped — это круто?
Заголовок раздела «Почему стили scoped — это круто?»<style> p { color: red; } /* Применяется ТОЛЬКО к p внутри этого компонента */</style>
<!-- Svelte компилирует это в: --><!-- p.svelte-x7k2p9 { color: red; } --><!-- И добавляет класс к элементу: <p class="svelte-x7k2p9"> -->Никаких конфликтов стилей между компонентами! 🎯
vite.config.ts — конфигурация сборщика ⚡
Заголовок раздела «vite.config.ts — конфигурация сборщика ⚡»import { defineConfig } from 'vite';import { svelte } from '@sveltejs/vite-plugin-svelte';
export default defineConfig({ plugins: [ svelte({ // Опции плагина (обычно берутся из svelte.config.js) configFile: './svelte.config.js', }), ],
// Сервер разработки server: { port: 5173, // Порт open: true, // Открыть браузер автоматически host: true, // Доступ из сети (0.0.0.0) },
// Сборка для production build: { outDir: 'dist', sourcemap: true, // Source maps для дебага minify: 'terser', // Минификация target: 'esnext', // Целевые браузеры rollupOptions: { output: { // Разделение чанков manualChunks: { 'vendor': ['svelte'], }, }, }, },
// Псевдонимы путей resolve: { alias: { '@': '/src', '$lib': '/src/lib', }, },});svelte.config.js — настройки компилятора ⚙️
Заголовок раздела «svelte.config.js — настройки компилятора ⚙️»import { vitePreprocess } from '@sveltejs/vite-plugin-svelte';
export default { // Препроцессоры — обработка <style lang="scss">, <script lang="ts"> и т.д. preprocess: vitePreprocess(),
// Настройки компилятора Svelte compilerOptions: { // Включить новый режим Svelte 5 (рекомендуется!) runes: true,
// Предупреждения (a11y и другие) warningFilter: (warning) => { // Отключить конкретные предупреждения if (warning.code === 'a11y-missing-attribute') return false; return true; }, },
// Для SvelteKit — настройка Kit // kit: { // adapter: adapter(), // },};Препроцессоры — расширяем возможности
Заголовок раздела «Препроцессоры — расширяем возможности»# Sass/SCSS стилиnpm install -D sass
# В компоненте:# <style lang="scss"># .container {# &__title { color: #ff3e00; }# }# </style>// svelte.config.js с несколькими препроцессорамиimport { vitePreprocess } from '@sveltejs/vite-plugin-svelte';import { preprocessMeltUI } from '@melt-ui/pp';import sequence from 'svelte-sequential-preprocessor';
export default { preprocess: sequence([ vitePreprocess(), preprocessMeltUI(), // MeltUI компоненты ]),};TypeScript в Svelte проекте 🔷
Заголовок раздела «TypeScript в Svelte проекте 🔷»TypeScript включён из коробки в шаблоне svelte-ts. Вот что важно знать:
// tsconfig.json — стандартная конфигурация{ "extends": "./.svelte-kit/tsconfig.json", // SvelteKit // или для Vite: "compilerOptions": { "target": "ES2022", "useDefineForClassFields": true, "module": "ESNext", "lib": ["ES2022", "DOM", "DOM.Iterable"], "moduleResolution": "bundler", "allowImportingTsExtensions": true, "resolveJsonModule": true, "isolatedModules": true, "noEmit": true, "strict": true, "noUnusedLocals": true, "noUnusedParameters": true, "noFallthroughCasesInSwitch": true }, "include": ["src/**/*.d.ts", "src/**/*.ts", "src/**/*.svelte"]}Типизация props в Svelte 5
Заголовок раздела «Типизация props в Svelte 5»<script lang="ts"> // Svelte 5: типизация через интерфейс interface Props { name: string; age?: number; onUpdate?: (value: string) => void; }
let { name, age = 18, onUpdate }: Props = $props();</script>Типизация событий и слотов
Заголовок раздела «Типизация событий и слотов»<script lang="ts"> // Типизация кастомных событий (Svelte 4 стиль) import { createEventDispatcher } from 'svelte';
const dispatch = createEventDispatcher<{ submit: { value: string; timestamp: number }; cancel: void; }>();
// Svelte 5 стиль — через props-функции let { onsubmit }: { onsubmit: (data: { value: string }) => void } = $props();</script>VS Code — настройка окружения 🖥️
Заголовок раздела «VS Code — настройка окружения 🖥️»Расширения
Заголовок раздела «Расширения»1. Svelte for VS Code (svelte.svelte-vscode) — ОБЯЗАТЕЛЬНО! - Syntax highlighting - IntelliSense и автодополнение - Форматирование кода - Диагностика ошибок TypeScript
2. Prettier - Code formatter (esbenp.prettier-vscode)3. ESLint (dbaeumer.vscode-eslint)settings.json
Заголовок раздела «settings.json»{ // Форматировать .svelte файлы через Prettier "[svelte]": { "editor.defaultFormatter": "svelte.svelte-vscode", "editor.formatOnSave": true },
// TypeScript — использовать workspace версию "typescript.tsdk": "node_modules/typescript/lib",
// Включить проверку типов в .svelte файлах "svelte.enable-ts-plugin": true,
// Автоимпорт компонентов "svelte.plugin.svelte.compilerWarnings": { "a11y-missing-attribute": "ignore", "a11y-missing-content": "ignore" }}.prettierrc для Svelte
Заголовок раздела «.prettierrc для Svelte»{ "useTabs": false, "singleQuote": true, "trailingComma": "es5", "printWidth": 100, "plugins": ["prettier-plugin-svelte"], "overrides": [ { "files": "*.svelte", "options": { "parser": "svelte" } } ]}Команды: запуск, сборка, превью 🏃
Заголовок раздела «Команды: запуск, сборка, превью 🏃»# Dev-сервер с HMR (Hot Module Replacement)npm run dev
# Dev-сервер доступный в локальной сетиnpm run dev -- --host
# Сборка для productionnpm run build
# Превью production-сборки локальноnpm run preview
# Проверка TypeScript без компиляцииnpx tsc --noEmit
# Линтингnpm run lint
# Форматированиеnpm run formatЧто происходит при npm run build?
Заголовок раздела «Что происходит при npm run build?»src/ App.svelte ──→ (Svelte компилятор) ──→ App.js (чистый JS!) main.ts ──→ (TypeScript) ──→ main.js ↓ (Vite Rollup) ↓dist/ index.html (с инжектированными скриптами) assets/ index-Abc123.js (bundle, минифицирован) index-Xyz789.css (стили)Svelte компилирует компоненты — в итоговом bundle нет Svelte runtime! Только твой код + маленький helpers файл (~8kb).
Первый компонент: Hello World на Svelte 👋
Заголовок раздела «Первый компонент: Hello World на Svelte 👋»Давай создадим полноценный компонент с состоянием, событиями и стилями:
<script lang="ts"> // Svelte 5: реактивное состояние через rune $state let name = $state('Яша'); let count = $state(0); let items = $state<string[]>(['Svelte', 'Vite', 'TypeScript']);
// Вычисляемое значение через $derived let doubled = $derived(count * 2); let greeting = $derived(`Привет, ${name}! 👋`);
// Функции обновления состояния function increment(): void { count++; }
function addItem(): void { const item = prompt('Добавить элемент:'); if (item) items = [...items, item]; }
function removeItem(index: number): void { items = items.filter((_, i) => i !== index); }</script>
<!-- Шаблон — никаких обёрток не нужно! --><main> <h1>{greeting}</h1>
<section class="counter"> <p>Счётчик: <strong>{count}</strong> (×2 = {doubled})</p> <div class="buttons"> <button onclick={() => count--}>−</button> <button onclick={increment}>+</button> <button onclick={() => count = 0} class="reset">сброс</button> </div> </section>
<section class="list"> <h2>Стек технологий:</h2> {#each items as item, i (item)} <div class="item"> <span>{i + 1}. {item}</span> <button onclick={() => removeItem(i)}>✕</button> </div> {/each} <button onclick={addItem} class="add">+ Добавить</button> </section></main>
<style> main { max-width: 500px; margin: 2rem auto; padding: 1rem; font-family: system-ui, sans-serif; }
h1 { color: #ff3e00; font-size: 2rem; }
.counter { background: #f8f8f8; padding: 1rem; border-radius: 8px; margin-bottom: 1rem; }
.buttons { display: flex; gap: 8px; }
button { padding: 0.5rem 1rem; border: none; border-radius: 6px; cursor: pointer; background: #ff3e00; color: white; font-size: 1rem; }
button.reset { background: #666; }
button.add { margin-top: 0.5rem; background: #40b3ff; }
.item { display: flex; justify-content: space-between; align-items: center; padding: 0.5rem; border-bottom: 1px solid #eee; }
.item button { background: transparent; color: #ff3e00; padding: 0.2rem 0.5rem; font-size: 0.8rem; }</style>// src/main.ts — точка входаimport { mount } from 'svelte';import './app.css';import App from './App.svelte';
const app = mount(App, { target: document.getElementById('app')!, props: { // Если нужно передать начальные props }});
export default app;Резюме 🏁
Заголовок раздела «Резюме 🏁»Что мы узнали:
- Vite + Svelte — для SPA, быстрый старт
- SvelteKit — для SSR/SSG, файловый роутинг, полноценные приложения
- .svelte файл — три секции:
<script>, шаблон,<style> - Scoped стили — по умолчанию, без конфликтов
- TypeScript — через
<script lang="ts"> - vite.config.ts — сборщик, плагины, dev-сервер
- svelte.config.js — компилятор, препроцессоры
Следующий шаг — базовый синтаксис: интерполяция, директивы классов и стилей! 📝