Если ты следишь за фронтендом, то наверняка помнишь, как долго экосистема Svelte шла к мажорной стабилизации компилятора Svelte 5 с его новой системой реактивных рун. Теперь пришло время следующего логического шага: команда официально выкатила мажорный релиз фреймворка SvelteKit 3, а вместе с ним представила стабильную версию CLI sv 1.0.
Это не просто дежурное обновление минорных зависимостей. Новая версия наводит генеральную уборку в накопившихся за годы легаси-решениях, избавляется от проприетарных фреймворковых костылей в пользу официальных веб-стандартов Node.js и полностью перекраивает поведение серверных адаптеров под современные бессерверные платформы.
Давай разберёмся по винтикам, что именно изменилось под капотом, какие привычные паттерны придётся переписать и как новая утилита sv автоматизирует болезненный процесс миграции.
Прощай, $lib: переход на стандартные Subpath Imports и единый vite.config.ts
Пожалуй, самое заметное синтаксическое изменение, с которым ты столкнёшься в первую минуту после обновления — это исчезновение привычного алиаса $lib.
В SvelteKit 1 и 2 знак доллара в начале импорта (import Button from '$lib/Button.svelte') был чисто внутренней магией фреймворка. Под капотом работала связка из плагинов Vite и настроек tsconfig.json, которая подменяла путь. Но эта магия регулярно вставляла палки в колёса внешним инструментам: линтеры ESLint, статические анализаторы Biome и современные среды исполнения вроде Bun или Deno постоянно спотыкались о нестандартный идентификатор.
В SvelteKit 3 разработчики беспощадно удалили $lib и перешли на нативный стандарт платформы ECMAScript — Subpath Imports с решёткой:
// Было в SvelteKit 2:
// import { formatDate } from '$lib/utils/format';
// Стало в SvelteKit 3:
import { formatDate } from '#lib/utils/format.js';
Поскольку этот механизм теперь резолвится через нативный механизм модулей платформы, появилось строгое требование: в импортах обязательно указывать точные расширения файлов (.js, .ts, .svelte).
Второе важное упрощение коснулось конфигурации. Раньше у тебя в корне проекта всегда лежали два файла-соседа: svelte.config.js и vite.config.ts. В первом настраивались адаптеры развёртывания и препроцессоры, а во втором — плагины сборщика. Это приводило к асинхронным задержкам при инициализации Vite. В третьей версии svelte.config.js больше не используется для опций SvelteKit: все параметры и адаптеры теперь объявляются внутри вызова плагина sveltekit() прямо в vite.config.ts.
Переворот в адаптерах: строгие workers в Cloudflare и хеширование ETag в Node
Если изменения в путях импорта утилита миграции берёт на себя, то серверный код потребует твоего непосредственного внимания. Больше всего изменений затронуло два самых популярных адаптера:
- Cloudflare Workers (
@sveltejs/adapter-cloudflare@8.0.0): Раньше для доступа к базам данных D1, хранилищу KV или очередям Cloudflare разработчики использовали глобальный объект платформыevent.platform.env.MY_KV. Это было источником постоянной путаницы: типы часто расходились с реальным окружением, а локальный эмулятор Miniflare вёл себя иначе, чем прод. В SvelteKit 3 объектplatformполностью удалён. Все биндинги теперь импортируются через эмулируемый виртуальный модульcloudflare:workers:
// src/routes/api/counter/+server.ts
import { env } from 'cloudflare:workers';
import { json } from '@sveltejs/kit';
export async function GET() {
// Прямой доступ к переменным окружения и хранилищу KV со строгой типизацией
const currentCount = (await env.COUNTER_KV.get('hits')) ?? '0';
const nextCount = parseInt(currentCount, 10) + 1;
await env.COUNTER_KV.put('hits', nextCount.toString());
return json({ hits: nextCount });
}
- Node.js (
@sveltejs/adapter-node@6.0.0): Команда полностью переписала логику отдачи статических файлов, отказавшись от старой библиотекиsirv. Теперь статический манифест предрассчитывается на этапе сборки. Каждый статический файл снабжается строгим заголовкомETagна основе криптографического хеша содержимого. Браузер мгновенно получает ответ304 Not Modifiedбез лишних системных вызовов к диску для проверки времени модификации файла. Но есть важное архитектурное ограничение: адаптер больше принципиально не отдаёт файлы, сгенерированные приложением динамически после старта контейнера. Если твой сервис генерировал PDF-отчёты в локальную папку со статикой, теперь их нужно отдавать через явный эндпоинт+server.tsили выгружать в S3-совместимое хранилище.
SvelteKit 3 требует Node.js версии не ниже v22.17, компилятор Svelte 5.57.1 или новее, Vite 8+ и TypeScript версии 6.0+. На старых версиях Node сборка завершится с ошибкой парсинга subpath imports.
Автоматическая миграция через CLI sv 1.0 и официальные дополнения
Чтобы разработчики не переписывали сотни импортов вручную, релиз сопровождается выпуском нового официального CLI sv 1.0. Для обновления проекта достаточно запустить команду:
# Запуск официального мастера обновления проекта
npx sv migrate sveltekit-3
Утилита пройдётся по всему коду, заменит $lib на #lib с правильными расширениями, перенесёт настройки адаптеров в vite.config.ts и обновит манифест package.json.
Кроме того, в sv 1.0 появился стандартизированный API дополнений (add-ons). Теперь для подключения официального плагина прогрессивной оптимизации картинок не нужно копаться в конфигах:
# Установка и автоматическая настройка дополнения enhanced-img
npx sv add enhanced-img
На что обратить внимание перед обновлением рабочего проекта
Я всегда советую подходить к мажорным релизам с холодной головой. Переход на SvelteKit 3 даёт ощутимый прирост: скорость холодного старта Vite заметно выросла, ETag-кеширование разгружает серверные ноды, а типизация Cloudflare стала монолитной.
Однако перед нажатием кнопки обновления проверь три вещи:
- Нет ли в твоём проекте самописной генерации временных файлов в публичную папку статики (при использовании
adapter-node). - Готовы ли твои CI/CD-раннеры к Node.js 22.17.
- Завершаются ли все фоновые мутации на клиенте явным вызовом
ignore()(сервер SvelteKit 3 теперь строго прерывает незавершённые параллельные single-flight запросы с ошибкой).
Если эти моменты учтены, запуск npx sv migrate sveltekit-3 превратит обновление в приятную получасовую прогулку.
