Svelte / SvelteKitSeniorExperience
Проект на Svelte / SvelteKit вырос из небольшого интерфейса в большой продукт. Какие архитектурные проблемы вы ожидаете увидеть?
При росте проекта типичные проблемы: утечка глобальных stores в SSR, плоская структура маршрутов без group layouts, отсутствие типизированного API-слоя и дублирование логики авторизации в каждом load().
Архитектурные проблемы при масштабировании Svelte / SvelteKit
Когда проект вырастает из MVP, накапливаются архитектурные долги, специфичные для Svelte/SvelteKit.
Состояние приложения
В маленьких проектах используют глобальные writable()-хранилища в src/lib/stores.ts. При росте:
- Хранилища становятся тесно связанными — изменение одного требует обновления десятков подписчиков.
- В SSR глобальные хранилища создаются один раз и могут утекать данные между запросами разных пользователей.
- Решение: переход на Svelte 5 Runes с
$state,$derivedи контекстную передачу состояния черезsetContext/getContext.
// src/lib/context/user.ts — безопасный контекст вместо глобального store
import { setContext, getContext } from 'svelte';
import { writable } from 'svelte/store';
const USER_KEY = Symbol('user');
export function initUserContext(initialUser: User | null) {
const store = writable(initialUser);
setContext(USER_KEY, store);
return store;
}
export function getUserContext() {
return getContext<ReturnType<typeof writable<User | null>>>(USER_KEY);
}
Структура маршрутов
- Плоская структура
src/routes/становится неудобной при 50+ страницах. - Отсутствие чёткого разделения на
+page.server.ts(данные) и+page.svelte(отображение) приводит к смешению логики. - Grouped routes
(marketing)/,(app)/позволяют использовать разные layouts без влияния на URL.
Переиспользование компонентов и дизайн-система
- Без договорённостей компоненты дублируются в разных частях приложения.
- Нет стандартного способа документирования — нужна интеграция с Histoire или Storybook (через
@storybook/svelte).
Типизация данных
- SvelteKit генерирует типы для параметров маршрутов в
.svelte-kit/types/, но их нужно явно импортировать. - При отсутствии строгой типизации
load()функций ошибки проявляются только в runtime.
// +page.server.ts — правильная типизация через PageServerLoad
import type { PageServerLoad } from './$types';
export const load: PageServerLoad = async ({ params, locals }) => {
const user = locals.user; // типизировано через app.d.ts
return { user };
};
API слой
- API-эндпоинты в
src/routes/api/смешиваются с страницами — трудно тестировать изолированно. - Нет единого места для HTTP-клиента — каждый компонент делает fetch по-своему.
- Решение: выделить
src/lib/api/с типизированными клиентами, использоватьtRPCилиzodios.
Производительность при большом числе компонентов
- Svelte не имеет виртуального DOM, но при большом числе реактивных зависимостей граф реактивности растёт.
- Компиляция
svelte-checkзамедляется при 500+ компонентах без incremental builds.
Подводные камни
- Глобальные
writable()хранилища утекают между SSR-запросами — использовать только черезsetContextв корневом layout. - Групповые layouts
(group)/+layout.svelteне наследуются автоматически — каждая вложенная группа нуждается в явном+layout.ts. - Миграция с Svelte 4 stores на Svelte 5 Runes требует переписывания всех реактивных зависимостей — нет автоматического кодмода.
- Vite HMR при большом числе файлов начинает тормозить без
optimizeDeps.includeвvite.config.ts. - SvelteKit не поддерживает изоморфные middleware — логику авторизации нужно дублировать в каждом
load()или централизовать через хукhandle. - Параметры маршрутов (
[id]) всегда строки — типовые ошибки при передаче числа скрыты без строгой типизацииPageParams. - Storybook для Svelte значительно отстаёт по функциональности от React-версии — рассмотрите Histoire как альтернативу.
- Отсутствие встроенного DI-контейнера затрудняет тестирование сервисного слоя — используйте паттерн factory functions с явными зависимостями.
What hurts your answer
- Говорить только о запуске Svelte / SvelteKit, но не об эксплуатации
- Не упоминать observability, обновления, безопасность и rollback
- Описывать риски абстрактно, без способов их снижать
What they're listening for
- Видит production-риски Svelte / SvelteKit
- Говорит про monitoring, rollout, rollback и безопасность
- Умеет ранжировать риски по вероятности и влиянию