Перейти к основному содержимому

Первая программа на Svelte

Разработчику Архитектору

Первая программа на Svelte

Svelte — фреймворк, который компилирует компоненты в эффективный JavaScript на этапе сборки. В runtime нет виртуального DOM, как в React — бандл меньше, ментальная модель проще для небольших UI.

Сборка и dev-server идут через Vite — сборка и dev-server. Сравнение синтаксиса с Vue — Первая программа на Vue.js.

ШагРезультат
1npm create svelte@latest — каркас проекта
2+page.svelte — счётчик и форма
3$state, $derived — реактивность Svelte 5
4Список с API — fetch к Node backend
5Дочерние компоненты — props и callbacks
6npm run build — production-сборка
МатериалЗачем
Vite — сборка и dev-serverHMR, proxy, env
Первая программа на Node.jsREST API на порту 3000
FullstackCORS, два порта
npmscripts, install
HTML — о разделеразметка в .svelte
TypeScriptопция в мастере create-svelte

Навигация по фронтенду

Svelte 5 runes

В этой статье используется синтаксис Svelte 5 ($state, $derived, $props). Старые проекты могут ещё использовать let count = 0 без runes — проверьте версию в package.json.


Как работает Svelte

ЭтапЧто происходит
РазработкаVite отдаёт модули, HMR обновляет компонент
СборкаКомпилятор Svelte генерирует прямой DOM-код
RuntimeМинимальная библиотека реактивности

В React компонент описывает что нарисовать, reconciler сравнивает деревья. В Svelte компилятор заранее генерирует код обновления DOM при изменении $state.


Шаг 1 — создание проекта

node -v
npm create svelte@latest my-svelte-app
cd my-svelte-app
npm install
npm run dev

В мастере на первый раз:

ВопросРекомендация
SvelteKit или SvelteSvelteKit (роутинг из коробки)
TypeScriptпо желанию (ниже — JavaScript)
ESLint / PrettierYes
Tailwindпо желанию

Откройте адрес из терминала (обычно http://localhost:5173).

Структура SvelteKit:

my-svelte-app/
src/
routes/
+page.svelte ← главная страница
+layout.svelte ← общая обёртка
lib/ ← переиспользуемые компоненты
vite.config.js
svelte.config.js
package.json

Разбор:

  • Файлы +page.svelte — маршруты (аналог pages в Next.js).
  • src/lib — импорт через $lib/... (алиас SvelteKit).
  • Vite под капотом — npm run dev запускает dev-server.

Шаг 2 — первый компонент

src/routes/+page.svelte:

<script>
let name = $state('Гость');
let count = $state(0);

const greeting = $derived(`Привет, ${name}!`);

function increment() {
count += 1;
}
</script>

<main>
<h1>{greeting}</h1>
<p>Счётчик: {count}</p>
<button type="button" onclick={increment}>+1</button>

<label>
Имя:
<input bind:value={name} />
</label>
</main>

<style>
main {
font-family: system-ui, sans-serif;
max-width: 32rem;
margin: 2rem auto;
padding: 0 1rem;
}
button {
margin-right: 0.5rem;
padding: 0.4rem 0.8rem;
}
</style>

Разбор:

  • $state(0) — реактивная переменная (Svelte 5 runes).
  • $derived(...) — вычисляемое значение, пересчитывается при смене name.
  • {greeting} — интерполяция в HTML (как {{ }} во Vue).
  • bind:value={name} — двусторонняя связь с input, аналог v-model во Vue.
  • onclick={increment} — обработчик без @ (можно и on:click в старом стиле).
  • <style> scoped по умолчанию — стили только для этого компонента.

Сохраните файл — страница обновится без полной перезагрузки (HMR).


Шаг 3 — условия и циклы

<script>
let items = $state(['Яблоко', 'Банан', 'Груша']);
let filter = $state('');

const visible = $derived(
items.filter((item) => item.toLowerCase().includes(filter.toLowerCase()))
);
</script>

<input placeholder="Фильтр" bind:value={filter} />

<ul>
{#each visible as item (item)}
<li>{item}</li>
{/each}
</ul>

{#if visible.length === 0}
<p>Ничего не найдено</p>
{/if}

Разбор:

  • {#each visible as item (item)} — цикл; (item) — key для стабильного DOM.
  • {#if} / {:else if} / {/if} — условный рендер.
  • $derived пересчитывает visible при изменении items или filter.

Шаг 4 — список заметок с API

Если запущен Node API на порту 3000:

src/routes/notes/+page.svelte:

<script>
let notes = $state([]);
let loading = $state(true);
let error = $state('');
let newText = $state('');

async function loadNotes() {
loading = true;
error = '';
try {
const res = await fetch('/api/notes');
if (!res.ok) throw new Error(`HTTP ${res.status}`);
notes = await res.json();
} catch (e) {
error = e.message;
} finally {
loading = false;
}
}

async function addNote() {
const text = newText.trim();
if (!text) return;
const res = await fetch('/api/notes', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ text }),
});
if (!res.ok) return;
newText = '';
await loadNotes();
}

$effect(() => {
loadNotes();
});
</script>

<h1>Заметки</h1>

{#if loading}
<p>Загрузка…</p>
{:else if error}
<p class="err">Ошибка: {error}</p>
{:else}
<ul>
{#each notes as note (note.id)}
<li>{note.text}</li>
{/each}
</ul>
{/if}

<form onsubmit={(e) => { e.preventDefault(); addNote(); }}>
<input bind:value={newText} placeholder="Новая заметка" />
<button type="submit">Добавить</button>
</form>

<style>
.err { color: #c00; }
</style>

Прокси к API

В vite.config.js (288):

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

export default defineConfig({
plugins: [sveltekit()],
server: {
proxy: {
'/api': {
target: 'http://127.0.0.1:3000',
changeOrigin: true,
rewrite: (path) => path.replace(/^\/api/, ''),
},
},
},
});

Запрос fetch('/api/notes') идёт через Vite на Node — CORS не мешает. Подробнее — Fullstack на JavaScript.


Шаг 5 — дочерний компонент

src/lib/Counter.svelte:

<script>
let { value = 0, onchange } = $props();

function inc() {
onchange?.(value + 1);
}
</script>

<button type="button" onclick={inc}>Счётчик: {value}</button>

Родитель src/routes/+page.svelte:

<script>
import Counter from '$lib/Counter.svelte';
let count = $state(0);
</script>

<Counter value={count} onchange={(v) => (count = v)} />
<p>Значение в родителе: {count}</p>

Разбор:

  • $props() — входные props (Svelte 5).
  • onchange?.(...) — optional callback вверх по дереву.
  • Props вниз, callback вверх — та же идея, что во Vue и React.

Шаг 6 — формы и локальное состояние

src/lib/NoteForm.svelte:

<script>
let { onsubmit } = $props();
let text = $state('');

function handleSubmit(e) {
e.preventDefault();
const trimmed = text.trim();
if (!trimmed) return;
onsubmit?.(trimmed);
text = '';
}
</script>

<form onsubmit={handleSubmit}>
<textarea bind:value={text} rows="3" placeholder="Текст заметки"></textarea>
<button type="submit">Сохранить</button>
</form>

Компонент не знает про API — только вызывает onsubmit. Родитель решает, куда отправить данные.


Svelte, React и Vue — обзор

SvelteReactVue
RuntimeминимальныйReact + reconcilerVue reactivity
Синтаксис.svelte файлJSX<template>
Обучениебыстрый стартhooks, ecosystemдирективы v-*
Экосystemменьше вакансиймаксимумширокий
СборкаVite / SvelteKitVite / CRAVite / Vue CLI

Svelte хорош для лендингов, дашбордов среднего размера и встраиваемых виджетов. Крупные команды чаще на React — но SvelteKit закрывает routing, SSR и адаптеры деплоя.


Production-сборка

npm run build
npm run preview
КомандаРезультат
buildОптимизированные файлы в .svelte-kit / build
previewЛокальный просмотр production

Для SvelteKit выберите adapter:

  • @sveltejs/adapter-static — статический хостинг;
  • @sveltejs/adapter-node — Node-сервер;
  • @sveltejs/adapter-vercel — Vercel.
Production

На статическом хостинге API должен быть на отдельном домене с CORS или через reverse proxy. Секреты не кладите в клиентский код — только VITE_* для публичных URL (288).


Упражнения

  1. Добавьте кнопку удаления заметки — DELETE /api/notes/:id.
  2. Сделайте компонент LoadingSpinner.svelte и используйте его в {#if loading}.
  3. Переведите проект на TypeScript — включите в мастере и типизируйте Note.
  4. Добавьте страницу /about через src/routes/about/+page.svelte.
  5. Сравните тот же UI на Vue — отметьте синтаксические отличия.

Частые ошибки и troubleshooting

СимптомПричинаРешение
Счётчик не обновляетсяЗабыли $state в Svelte 5Оберните значение в $state(...)
CORS при fetchПрямой URL :3000 из :5173Прокси в vite.config.js288
{#each} без keyНестабильный DOMДобавьте (note.id)
$effect в бесконечном циклеМутируете state внутри effectРазделите load и render
Cannot find $lib/...Файл вне src/libПереместите или исправьте путь
HMR не срабатываетОшибка синтаксисаСмотрите overlay в браузере
Пустой buildНеверный adapterПроверьте svelte.config.js

FAQ

Svelte или SvelteKit?

Svelte — язык компонентов. SvelteKit — meta-framework (роутинг, SSR, adapters). Для новых проектов берите SvelteKit.

Нужен ли TypeScript?

Не обязателен, но рекомендуется для средних проектов — TypeScript.

Как подключить UI-библиотеку?

Skeleton, shadcn-svelte, Flowbite-Svelte — через npm. Стили scoped в компонентах совместимы с Tailwind.

Svelte 4 и Svelte 5 в одном проекте?

Миграция через runes — см. официальный guide. Новые статьи ориентированы на Svelte 5.


Шаг 7 — SvelteKit routing и layout

src/routes/+layout.svelte — общая обёртка:

<script>
let { children } = $props();
</script>

<header>
<nav>
<a href="/">Главная</a>
<a href="/notes">Заметки</a>
</nav>
</header>

{@render children()}

<style>
nav a { margin-right: 1rem; }
header { padding: 1rem; border-bottom: 1px solid #ddd; }
</style>

src/routes/notes/+page.svelte — страница списка (код из шага 4).

ФайлURL
+page.svelte/
notes/+page.svelte/notes
notes/[id]/+page.svelte/notes/42

Динамический маршрут src/routes/notes/[id]/+page.svelte:

<script>
let { data } = $props();
</script>

<h1>Заметка #{data.id}</h1>
<p>{data.text}</p>

+page.server.js (load data на сервере SvelteKit):

export async function load({ params, fetch }) {
const res = await fetch(`/api/notes/${params.id}`);
if (!res.ok) throw new Error('Not found');
return res.json();
}

Шаг 8 — stores (глобальное состояние)

Для простых случаев — runes в $lib. Для shared state — svelte/store:

src/lib/theme.svelte.js:

import { writable } from 'svelte/store';

export const theme = writable('light');

Использование (Svelte 4 style) или обёртка через $state в Svelte 5.

Для крупных приложений — см. официальный svelte/store и паттерн context.


Шаг 9 — TypeScript в Svelte

При создании проекта выберите TypeScript. Типизация props:

<script lang="ts">
interface Note {
id: number;
text: string;
}

let { notes = [] }: { notes: Note[] } = $props();
</script>

Подробнее о типах — TypeScript.


Шаг 10 — тестирование компонентов

npm i -D vitest @testing-library/svelte

vite.config.js:

test: {
environment: 'jsdom',
include: ['src/**/*.test.js'],
},

src/lib/Counter.svelte.test.js:

import { render, fireEvent } from '@testing-library/svelte';
import Counter from './Counter.svelte';

test('increments on click', async () => {
let value = 0;
const { getByRole } = render(Counter, {
props: { value, onchange: (v) => (value = v) },
});
await fireEvent.click(getByRole('button'));
expect(value).toBe(1);
});
npx vitest

Vitest использует тот же Vite config — быстрый запуск.


Шаг 11 — SSR и adapter

SvelteKit рендерит HTML на сервере при первом запросе. svelte.config.js:

import adapter from '@sveltejs/adapter-node';

export default {
kit: {
adapter: adapter(),
},
};
AdapterДеплой
adapter-staticNetlify, GitHub Pages
adapter-nodeVPS, Docker
adapter-vercelVercel
npm run build
node build/index.js

Fullstack dev workflow

Терминал 1: cd notes-api && npm run dev (262).

Терминал 2: cd my-svelte-app && npm run dev.


Расширенный troubleshooting

СимптомДетали
500 на +page.server.jsAPI недоступен — проверьте proxy
$props() undefinedSvelte 5 — обновите родителя
FOUC стилей+layout.svelte import CSS
SEO пустойSSR включён в SvelteKit по умолчанию
Build size большойcode-split через dynamic import

Дополнительные упражнения

  1. Страница /notes/[id] с удалением через DELETE.
  2. Компонент ErrorBanner.svelte для error state.
  3. Dark theme через CSS variables и $state.
  4. Vitest-тест формы NoteForm.
  5. Deploy на Vercel через adapter-vercel.

Production checklist

ПунктДействие
adapter-*Выбран под хостинг
Env API URLПубличный URL backend
CORS или same-originНастроен proxy/nginx
Cache headersСтатика на CDN
AnalyticsОтложенная загрузка

Справочник runes Svelte 5

RuneНазначениеПример
$stateРеактивная переменнаяlet n = $state(0)
$derivedВычисляемое значение$derived(n * 2)
$effectПобочный эффектfetch при mount
$propsВходные propslet { x } = $props()
$bindableДвусторонний propредко, для forms

Старый синтаксис Svelte 4 ($: doubled = n * 2) заменён на $derived — при миграции смотрите официальный guide.


Анимации и transitions

<script>
import { fade, fly } from 'svelte/transition';
let visible = $state(true);
</script>

{#if visible}
<p transition:fade>Исчезну с fade</p>
{/if}

<button onclick={() => (visible = !visible)}>Toggle</button>

Svelte анимирует enter/leave DOM без сторонних библиотек.


Работа с формами и actions

<form method="POST" action="?/create">
<input name="text" required />
<button>Отправить</button>
</form>

SvelteKit form actions обрабатывают POST на сервере без отдельного API — progressive enhancement. Подробнее в документации SvelteKit; для учебного API остаётся fetch + Node.


Доступность (a11y)

  • Используйте <button type="button"> для кликов, не <div onclick>.
  • <label> связан с <input> — клик по label фокусирует поле.
  • Сообщения об ошибках — aria-live="polite" для screen readers.

Сравнение fetch-паттернов

ПодходПлюсыМинусы
$effect + fetchПросто для учёбыНет cancel при unmount
onMount (Svelte 4)Явный lifecycleУстаревает в Svelte 5
SvelteKit loadSSR, SEOНужен server route
TanStack QueryCache, retryДоп. зависимость

Для production SPA часто добавляют TanStack Query; для первого проекта хватит $effect.


Конфигурация vite.config.js (SvelteKit)

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

export default defineConfig({
plugins: [sveltekit()],
server: {
port: 5173,
proxy: {
'/api': {
target: 'http://127.0.0.1:3000',
changeOrigin: true,
rewrite: (p) => p.replace(/^\/api/, ''),
},
},
},
});

См. полный разбор proxy — Vite — сборка и dev-server.


Environment variables в SvelteKit

Публичные переменные — префикс по правилам SvelteKit (PUBLIC_ в .env):

PUBLIC_API_URL=http://127.0.0.1:3000
import { PUBLIC_API_URL } from '$env/static/public';

Секреты — только в +page.server.js, не в клиентском коде.



Второй проход — расширенный практикум (Svelte)

Серия мини-туториалов

Туториал 1 — Stores writable

Команда или API: import { writable } from 'svelte/store'.

Детали: shared state между routes.

// пример шага
console.log('ok');
ШагПроверка
1Выполнить Stores writable
2Перезапустить dev-сервер
3Убедиться в отсутствии ошибок в консоли

Туториал 2 — Derived store

Команда или API: derived(count, $c => $c * 2).

Детали: реактивные вычисления.

// пример шага
console.log('ok');
ШагПроверка
1Выполнить Derived store
2Перезапустить dev-сервер
3Убедиться в отсутствии ошибок в консоли

Туториал 3 — Snippets Svelte 5

Команда или API: {#snippet row(item)}.

Детали: переиспользование markup.

// пример шага
console.log('ok');
ШагПроверка
1Выполнить Snippets Svelte 5
2Перезапустить dev-сервер
3Убедиться в отсутствии ошибок в консоли

Туториал 4 — Actions use:

Команда или API: function clickOutside(node).

Детали: DOM behavior без компонента.

// пример шага
console.log('ok');
ШагПроверка
1Выполнить Actions use:
2Перезапустить dev-сервер
3Убедиться в отсутствии ошибок в консоли

Туториал 5 — Transitions

Команда или API: transition:fade.

Детали: анимация списка notes.

// пример шага
console.log('ok');
ШагПроверка
1Выполнить Transitions
2Перезапустить dev-сервер
3Убедиться в отсутствии ошибок в консоли

Туториал 6 — load function

Команда или API: +page.js export load.

Детали: SSR data в SvelteKit.

// пример шага
console.log('ok');
ШагПроверка
1Выполнить load function
2Перезапустить dev-сервер
3Убедиться в отсутствии ошибок в консоли

Туториал 7 — form actions

Команда или API: +page.server.js actions.

Детали: POST без client fetch.

// пример шага
console.log('ok');
ШагПроверка
1Выполнить form actions
2Перезапустить dev-сервер
3Убедиться в отсутствии ошибок в консоли

Туториал 8 — hooks handle

Команда или API: hooks.server.js.

Детали: auth check все routes.

// пример шага
console.log('ok');
ШагПроверка
1Выполнить hooks handle
2Перезапустить dev-сервер
3Убедиться в отсутствии ошибок в консоли

Туториал 9 — adapter-node

Команда или API: npm i -D @sveltejs/adapter-node.

Детали: deploy Node server.

// пример шага
console.log('ok');
ШагПроверка
1Выполнить adapter-node
2Перезапустить dev-сервер
3Убедиться в отсутствии ошибок в консоли

Туториал 10 — i18n

Команда или API: svelte-i18n.

Детали: локализация строк UI.

// пример шага
console.log('ok');
ШагПроверка
1Выполнить i18n
2Перезапустить dev-сервер
3Убедиться в отсутствии ошибок в консоли

Расширенные упражнения (второй проход)

  1. DELETE note кнопка с confirm dialog.

Подсказка к упражнению 13: Начните с минимального изменения, затем добавьте тест. Тема: DELETE.

  1. LoadingSpinner component в {#if loading}.

Подсказка к упражнению 14: Начните с минимального изменения, затем добавьте тест. Тема: LoadingSpinner.

  1. TypeScript Note interface в +page.svelte.

Подсказка к упражнению 15: Начните с минимального изменения, затем добавьте тест. Тема: TypeScript.

  1. Страница /about с layout наследованием.

Подсказка к упражнению 16: Начните с минимального изменения, затем добавьте тест. Тема: Страница.

  1. Сравните синтаксис с Vue doc.

Подсказка к упражнению 17: Начните с минимального изменения, затем добавьте тест. Тема: Сравните.

  1. Optimistic UI add note до ответа server.

Подсказка к упражнению 18: Начните с минимального изменения, затем добавьте тест. Тема: Optimistic.

  1. Error boundary {#await} блок.

Подсказка к упражнению 19: Начните с минимального изменения, затем добавьте тест. Тема: Error.

  1. Keyboard shortcut Ctrl+N новая note.

Подсказка к упражнению 20: Начните с минимального изменения, затем добавьте тест. Тема: Keyboard.

  1. Persist filter в sessionStorage.

Подсказка к упражнению 21: Начните с минимального изменения, затем добавьте тест. Тема: Persist.

  1. Unit test logic extract в notes.ts.

Подсказка к упражнению 22: Начните с минимального изменения, затем добавьте тест. Тема: Unit.


Расширенный FAQ (второй проход)

Svelte 4 migration?

Runes opt-in постепенно, см. migration guide.

SSR hydration mismatch?

Проверьте browser-only API в onMount.

SEO SvelteKit?

ssr true, meta tags в svelte:head.

PWA?

vite-plugin-pwa в SvelteKit config.

CSS framework?

Tailwind через skeleton или unstyled components.

Auth?

hooks.server.js session cookie + load redirect.

WebSocket notes?

onMount subscribe, onDestroy cleanup.

Bundle size?

analyze через rollup-plugin-visualizer.

Test components?

Vitest + @testing-library/svelte.

Deploy static?

adapter-static prerender all pages.


Production — дополнительные рекомендации

#ПрактикаЗачем
1adapter-nodeadapter-node за reverse proxy TLS
2Cache-ControlCache-Control static assets CDN
3EnvEnv PUBLIC_ prefix только public vars
4ErrorError tracking Sentry browser SDK
5LazyLazy load heavy components import()
6A11yA11y audit axe in CI
7RateRate limit API отдельно от static
8PreviewPreview deploy per PR Vercel

Troubleshooting — расширенная таблица

СимптомВероятная причинаДействие
Сборка падает без текстаКэш или версия NodeОчистить node_modules, lock-файл, переустановить
Тесты flakyПорядок или timingИзолировать example, убрать sleep, добавить wait matchers
Production 502Process не слушает PORTПроверить env PORT и health endpoint
Данные пропали после deployIn-memory store или migrateПодключить БД, migrate deploy
CORS в браузереПрямой URL APIProxy dev или enableCors origin
Медленный первый запросCold start DB poolWarmup health check после deploy
Ошибка подписи iOSCertificate expiredRenew в Developer portal, download profiles
Turbo frame blankId mismatchСверить turbo-frame id в request и response
Prisma client outdatedSchema changednpx prisma generate после migrate
Vite blank prodНеверный base pathПроверить base и URL деплоя

Пошаговый walkthrough — контрольный список

День 1

  1. Шаг 1 дня 1: закрепить часть стека Svelte. Запишите результат в README проекта.
# checkpoint
npm test || bundle exec rspec || echo manual check
  1. Шаг 2 дня 1: закрепить часть стека Svelte. Запишите результат в README проекта.
# checkpoint
npm test || bundle exec rspec || echo manual check
  1. Шаг 3 дня 1: закрепить часть стека Svelte. Запишите результат в README проекта.
# checkpoint
npm test || bundle exec rspec || echo manual check
  1. Шаг 4 дня 1: закрепить часть стека Svelte. Запишите результат в README проекта.
# checkpoint
npm test || bundle exec rspec || echo manual check
  1. Шаг 5 дня 1: закрепить часть стека Svelte. Запишите результат в README проекта.
# checkpoint
npm test || bundle exec rspec || echo manual check

День 2

  1. Шаг 1 дня 2: закрепить часть стека Svelte. Запишите результат в README проекта.
# checkpoint
npm test || bundle exec rspec || echo manual check
  1. Шаг 2 дня 2: закрепить часть стека Svelte. Запишите результат в README проекта.
# checkpoint
npm test || bundle exec rspec || echo manual check
  1. Шаг 3 дня 2: закрепить часть стека Svelte. Запишите результат в README проекта.
# checkpoint
npm test || bundle exec rspec || echo manual check
  1. Шаг 4 дня 2: закрепить часть стека Svelte. Запишите результат в README проекта.
# checkpoint
npm test || bundle exec rspec || echo manual check
  1. Шаг 5 дня 2: закрепить часть стека Svelte. Запишите результат в README проекта.
# checkpoint
npm test || bundle exec rspec || echo manual check

День 3

  1. Шаг 1 дня 3: закрепить часть стека Svelte. Запишите результат в README проекта.
# checkpoint
npm test || bundle exec rspec || echo manual check
  1. Шаг 2 дня 3: закрепить часть стека Svelte. Запишите результат в README проекта.
# checkpoint
npm test || bundle exec rspec || echo manual check
  1. Шаг 3 дня 3: закрепить часть стека Svelte. Запишите результат в README проекта.
# checkpoint
npm test || bundle exec rspec || echo manual check
  1. Шаг 4 дня 3: закрепить часть стека Svelte. Запишите результат в README проекта.
# checkpoint
npm test || bundle exec rspec || echo manual check
  1. Шаг 5 дня 3: закрепить часть стека Svelte. Запишите результат в README проекта.
# checkpoint
npm test || bundle exec rspec || echo manual check

День 4

  1. Шаг 1 дня 4: закрепить часть стека Svelte. Запишите результат в README проекта.
# checkpoint
npm test || bundle exec rspec || echo manual check
  1. Шаг 2 дня 4: закрепить часть стека Svelte. Запишите результат в README проекта.
# checkpoint
npm test || bundle exec rspec || echo manual check
  1. Шаг 3 дня 4: закрепить часть стека Svelte. Запишите результат в README проекта.
# checkpoint
npm test || bundle exec rspec || echo manual check
  1. Шаг 4 дня 4: закрепить часть стека Svelte. Запишите результат в README проекта.
# checkpoint
npm test || bundle exec rspec || echo manual check
  1. Шаг 5 дня 4: закрепить часть стека Svelte. Запишите результат в README проекта.
# checkpoint
npm test || bundle exec rspec || echo manual check

День 5

  1. Шаг 1 дня 5: закрепить часть стека Svelte. Запишите результат в README проекта.
# checkpoint
npm test || bundle exec rspec || echo manual check
  1. Шаг 2 дня 5: закрепить часть стека Svelte. Запишите результат в README проекта.
# checkpoint
npm test || bundle exec rspec || echo manual check
  1. Шаг 3 дня 5: закрепить часть стека Svelte. Запишите результат в README проекта.
# checkpoint
npm test || bundle exec rspec || echo manual check
  1. Шаг 4 дня 5: закрепить часть стека Svelte. Запишите результат в README проекта.
# checkpoint
npm test || bundle exec rspec || echo manual check
  1. Шаг 5 дня 5: закрепить часть стека Svelte. Запишите результат в README проекта.
# checkpoint
npm test || bundle exec rspec || echo manual check

День 6

  1. Шаг 1 дня 6: закрепить часть стека Svelte. Запишите результат в README проекта.
# checkpoint
npm test || bundle exec rspec || echo manual check
  1. Шаг 2 дня 6: закрепить часть стека Svelte. Запишите результат в README проекта.
# checkpoint
npm test || bundle exec rspec || echo manual check
  1. Шаг 3 дня 6: закрепить часть стека Svelte. Запишите результат в README проекта.
# checkpoint
npm test || bundle exec rspec || echo manual check
  1. Шаг 4 дня 6: закрепить часть стека Svelte. Запишите результат в README проекта.
# checkpoint
npm test || bundle exec rspec || echo manual check
  1. Шаг 5 дня 6: закрепить часть стека Svelte. Запишите результат в README проекта.
# checkpoint
npm test || bundle exec rspec || echo manual check

День 7

  1. Шаг 1 дня 7: закрепить часть стека Svelte. Запишите результат в README проекта.
# checkpoint
npm test || bundle exec rspec || echo manual check
  1. Шаг 2 дня 7: закрепить часть стека Svelte. Запишите результат в README проекта.
# checkpoint
npm test || bundle exec rspec || echo manual check
  1. Шаг 3 дня 7: закрепить часть стека Svelte. Запишите результат в README проекта.
# checkpoint
npm test || bundle exec rspec || echo manual check
  1. Шаг 4 дня 7: закрепить часть стека Svelte. Запишите результат в README проекта.
# checkpoint
npm test || bundle exec rspec || echo manual check
  1. Шаг 5 дня 7: закрепить часть стека Svelte. Запишите результат в README проекта.
# checkpoint
npm test || bundle exec rspec || echo manual check

Чек-лист самопроверки перед сдачей практикума

  • Проект создаётся с нуля по статье без пропусков шагов

  • CRUD или эквивалентный сценарий работает end-to-end

  • Есть обработка ошибок валидации или 404

  • Данные переживают перезапуск там, где это требуется темой

  • Написан минимум один автоматический тест или system check

  • Production-секция прочитана и применена к деплою или Docker

  • FAQ просмотрен — типичные ошибки воспроизведены и исправлены

  • Связанные материалы открыты для следующего шага обучения

Связанные материалы

ТемаМатериал
ViteVite — сборка и dev-server
VueПервая программа на Vue.js
ReactПервая программа на React
Node APIПервая программа на Node.js
Express CORSExpress — middleware
npmnpm — команды и lock-файлы
HTMLHTML — о разделе
ГалереяVue и Svelte — лаборатория

Содержание