Svelte
Руны: явная реактивность
Разработчик с опытом Svelte 3 открывает код на Svelte 5 и спотыкается: где привычная метка доллар-двоеточие, что за доллар-state, и почему это похоже на вызов функции, но в импортах его нет. До октября 2024 реактивность в Svelte была неявной: компилятор сам решал, что считать реактивным, по тому, где объявлена переменная. Это работало, пока компонент маленький, но плохо масштабировалось и не выходило за пределы .svelte файла. Svelte 5 сделал реактивность явной через руны - специальные слова со знаком доллара, которые компилятор узнаёт в коде.
- Миграция кодовых баз с Svelte 4 на 5: команды переписывают реактивные переменные на руну `$state`
- Общее состояние приложения выносят в файлы .svelte.js, где руны работают так же, как в компонентах
- Документация и обучающие материалы 2025-2026 годов написаны уже на рунах как стандарте
- Линтеры и редакторы подсвечивают руны как ключевые слова, помогая отличать их от обычных функций
- Сигнальная модель под рунами даёт более предсказуемое отслеживание зависимостей в крупных компонентах
Предварительные знания
- Структура .svelte компонента и блок script
- JavaScript: переменные, функции, разница между объявлением и вызовом
- Понимание, что Svelte - это компилятор, а не рантайм-библиотека
От доллар-двоеточия к рунам
В Svelte 3 и 4 реактивность держалась на двух соглашениях. Любая переменная верхнего уровня в компоненте считалась реактивной, а вычисляемые значения объявлялись через метку доллар-двоеточие. Это выглядело магически чисто, но имело цену: правила были неявными, реактивность не работала вне .svelte файла, а в больших компонентах было трудно понять, что от чего зависит. Готовя Svelte 5, команда во главе с Rich Harris перешла на сигнальную модель и сделала реактивность явной. Руны со знаком доллара - это сигналы под капотом, описанные понятным синтаксисом. Релиз Svelte 5 в октябре 2024 закрепил руны как основной способ работы с реактивностью.
Что такое руна
Руна - это специальное слово со знаком доллара в начале, которое компилятор Svelte 5 распознаёт как инструкцию о реактивности. Внешне руна похожа на вызов функции: `$state(0)` выглядит как функция с аргументом. Но это иллюзия. Руну не нужно импортировать, она не существует как функция в рантайме. Знак доллара - это синтаксический маркер, который видит компилятор и превращает в реактивный сигнал.
Переменная count объявлена через `$state`, и теперь её изменение реактивно: при count++ обновится текст кнопки. Компилятор увидел руну и сгенерировал код, который связывает значение с разметкой. Импорта руны в начале файла нет, потому что руна - часть языка шаблонов Svelte, а не библиотечная функция.
- Обычная функция — Импортируется из модуля, существует в рантайме, может быть передана как значение, переименована, вызвана динамически
- Руна — Ключевое слово компилятора со знаком доллара. Не импортируется, не существует как значение, понимается на этапе компиляции. Писать её можно только в разрешённых местах
Поскольку руна - ключевое слово, а не функция, её нельзя присвоить переменной, передать как аргумент или вызвать через ссылку. Запись вроде const s равно доллар-state не имеет смысла. Руна применяется прямо там, где объявляется реактивное значение.
Почему руну `$state` не нужно импортировать в начале файла?
Что было до рун в Svelte 4
В Svelte 4 реактивность была неявной. Любая переменная верхнего уровня в компоненте автоматически считалась реактивной, а вычисляемые значения и побочные эффекты объявлялись через метку доллар-двоеточие перед выражением. Компилятор сам угадывал зависимости. Это давало чистый вид, но имело три слабых места.
| Слабость Svelte 4 | Решение в Svelte 5 |
|---|---|
| Реактивность работала только в .svelte файлах | Руны работают и в модулях .svelte.js |
| Что реактивно, решал компилятор неявно | Реактивность объявлена явно руной |
| Метка доллар-двоеточие смешивала вычисления и эффекты | Раздельные руны: `$derived` и `$effect` |
| В больших компонентах трудно проследить зависимости | Зависимости видны по месту применения руны |
Метка доллар-двоеточие совмещала две разные вещи: вычисляемое значение и побочный эффект. В Svelte 5 их разделили на `$derived` (вычислить значение) и `$effect` (выполнить эффект), и код стал яснее для чтения и проверки.
В чём было главное ограничение неявной реактивности Svelte 4 по сравнению с рунами?
Пять основных рун
Реактивная модель Svelte 5 держится на пяти основных рунах. Каждая отвечает за свою задачу: хранить состояние, вычислять производное, запускать эффект, принимать входные данные, разрешать двустороннюю привязку. Есть и служебные руны, например `$inspect` для отладки. Этот урок даёт карту, а каждой руне посвящён отдельный урок дальше.
| Руна | Зачем нужна |
|---|---|
| `$state` | Объявить реактивное состояние, меняемое как обычная переменная |
| `$derived` | Вычислить значение из другого состояния, пересчёт автоматический |
| `$effect` | Выполнить побочный эффект после обновления DOM |
| `$props` | Получить входные данные компонента от родителя |
| `$bindable` | Разрешить двустороннюю привязку конкретного prop |
Здесь видна вся карта в действии: `$props` принимает label от родителя, `$state` хранит count, `$derived` считает doubled, `$effect` синхронизирует заголовок вкладки с состоянием. Пятая руна `$bindable` нужна, когда родитель и потомок должны делить одно значение в обе стороны, и о ней речь в уроке про props.
Какая руна отвечает за вычисление значения из другого реактивного состояния с автоматическим пересчётом?
Связь с другими темами
Руны - вход в модуль реактивности. Дальше курс разбирает каждую руну отдельно:
- Компонент .svelte — Руны живут в блоке script компонента или в модулях .svelte.js
- Реактивное состояние `$state` — Базовая руна, с которой начинается любая реактивность
- Зачем нужен Svelte — Руны продолжают идею компилятора: реактивность отслеживается на этапе сборки
Итог
- Руны - это специальные слова со знаком доллара, которые компилятор Svelte 5 узнаёт как ключевые конструкции реактивности
- Знак доллара здесь - не вызов функции и не переменная: руны не импортируют, их понимает сам компилятор
- Руны заменили неявную реактивность Svelte 4 (переменные верхнего уровня и метка доллар-двоеточие) на явную
- Пять основных рун: `$state`, `$derived`, `$effect`, `$props`, `$bindable`, плюс служебные вроде `$inspect`
- Руны работают не только в компонентах, но и в модулях .svelte.js и .svelte.ts, что выносит реактивное состояние за пределы компонента
Связанные уроки
- sv-03-components — Руны пишутся внутри script компонента, поэтому сначала нужна структура .svelte файла
- sv-06-state — Первая и базовая руна `$state` разбирается подробно в следующем уроке
- sv-01-why-svelte — Руны - продолжение истории Svelte как компилятора: реактивность теперь видна явно