Первый компонент: один файл .svelte
Файл .svelte — это один компонент: скрипт, разметка и стили в одном месте, как HTML, но с суперспособностями.
«Один компонент — один файл.» Это правило делает Svelte-проекты предсказуемыми: вы всегда знаете, где искать логику, разметку и стиль конкретного блока интерфейса.
Базовая единица Svelte — компонент, и живёт он в файле с расширением .svelte. Такой файл состоит из трёх необязательных частей: блок script с логикой на JavaScript, разметка (обычный HTML с добавками Svelte) и блок style с CSS. Все три части описывают один кусок интерфейса. Это похоже на однофайловые компоненты Vue, но синтаксис ближе к чистому HTML.
Самое приятное — насколько мало кода нужно для рабочего компонента. Объявите переменную в скрипте, и вы тут же можете вставить её в разметку через фигурные скобки. Никаких шаблонных движков со своим языком, никаких директив для простого вывода значения. Если переменная реактивная (об этом — следующий раздел), интерфейс сам обновится при её изменении.
Посмотрим на классический первый компонент — счётчик. Обратите внимание: код для нажатия выглядит как обычное присваивание, потому что так и есть.
<script>
let count = $state(0);
function increment() {
count += 1;
}
</script>
<button onclick={increment}>
Нажали раз: {count}
</button>
<style>
button { font-size: 1.2rem; padding: 0.5rem 1rem; }
</style>Здесь $state(0) — это руна, делающая переменную реактивной (подробно в следующем разделе). Выражение {count} в разметке вставляет текущее значение. Обработчик onclick — это обычный DOM-атрибут события, а не специальная директива. И стили в блоке style по умолчанию изолированы: они применятся только к этому компоненту, а не утекут на весь сайт.
Как это работает под капотом
Компилятор Svelte разбирает этот файл и превращает его в JavaScript-функцию, которая создаёт элементы, навешивает обработчик и — главное — запоминает, что текстовый узел внутри кнопки зависит от count. Когда count меняется, генерируется вызов, обновляющий ровно этот текст. Стили компилятор переписывает, добавляя к селекторам уникальный хеш-класс, чтобы добиться изоляции без дополнительных усилий с вашей стороны.
Counter.svelte компилятор браузер
----------------- ---------- ----------
<script> count </script> -> create_fragment() -> <button>...</button>
<button>{count}</button> -> update(count) -> textNode.data = count
<style> button {} </style> -> .button.svelte-x -> изолированный CSSЧастые ошибки
- Пытаться импортировать .svelte как обычный JS-модуль и запускать в Node. Файл нужно сначала скомпилировать сборщиком (Vite).
- Забыть про
$stateв Svelte 5. Простоеlet count = 0в рантайм-режиме не будет реактивным. - Ожидать, что стили глобальны. По умолчанию они изолированы; для глобальных нужен модификатор
:global(...).
Best practices
- Держите компоненты маленькими и сфокусированными на одной задаче — так их легче переиспользовать.
- Имена файлов компонентов пишите с заглавной:
Counter.svelte,UserCard.svelte. - Используйте изоляцию стилей как преимущество: не бойтесь простых селекторов вроде
button— они не утекут наружу.
От одного компонента к приложению
Один компонент-счётчик кажется игрушкой, но именно из таких кирпичиков складываются настоящие интерфейсы. Реальное приложение — это десятки и сотни компонентов, каждый из которых отвечает за свой маленький кусок: кнопка, карточка товара, форма входа, список комментариев. Компоненты импортируют друг друга и вкладываются один в другой, образуя дерево. Поскольку каждый компонент изолирован — его стили не утекают, его состояние локально, — вы можете рассуждать о нём отдельно, не держа в голове весь проект. Это и есть главная ценность компонентного подхода: сложность разбивается на управляемые части. Когда вы привыкнете мыслить компонентами, проектирование интерфейса превратится в вопрос «из каких блоков он состоит и как они общаются», а не «как написать одну гигантскую страницу».
Итог: компонент Svelte — это один .svelte-файл со скриптом, разметкой и стилями. Переменные вставляются в разметку фигурными скобками, события вешаются как обычные DOM-атрибуты, а стили изолированы по умолчанию.