Заблуждение: «Фронтенд — это не бэкенд». Взгляд на эволюцию архитектуры

Однажды я переносил логику из одного места в другое на фронте. Я сделал слои: сервисы, репозитории, модели. Я сделал так, как привык на бэкенде. И коллега спросил:

«Почему так сложно? Обычно на фронте делают иначе».

Это заставило меня задуматься. А почему, собственно, иначе?

Потому что фронтенд как индустрия моложе. Он только учится на своих граблях. А бэкенд уже прошёл этот путь. И сейчас фронтенд во многом повторяет его эволюцию — те же этапы, те же проблемы и те же решения.

В этой статье я разберу:

1. Как бэкенд эволюционировал от хаоса к микросервисам;

2. Как фронтенд сейчас проходит те же этапы;

3. Три архитектурных подхода — луковая, плагинная и событийная — которые пришли из бэкенда и теперь помогают строить надёжный фронтенд.

Часть 1. Путь бэкенда

В 2000-х бэкенд часто был хаотичным. PHP-скрипт мог содержать SQL-запросы, HTML-вёрстку и бизнес-логику в одном файле. Изменение одной цены товара иногда ломало соседние страницы.

Что бэкенд со временем осознал:

1. Слои. Не стоит смешивать всё подряд. Появился MVC;

2. Зависимости. Лучше, когда модули общаются через чёткие интерфейсы, а не ссылаются друг на друга напрямую. Появился Dependency Injection;

3. Масштаб. Монолит становится тесным. Появились микросервисы;

4. Состояние. Глобальные переменные ненадёжны. Появились Event Sourcing и CQRS.

Сегодня бэкенд — это про архитектуру, а не про выбор базы данных. Там говорят о гексагональной архитектуре, луковой модели, чистых слоях.

2010–2015: Спагетти на jQuery Файл script.js разрастался до тысяч строк. Коллбэки вкладывались в коллбэки. Отследить, где меняется переменная isUserLoggedIn, было сложно.

2015–2020: MVC для фронта (React/Vue/Angular) Появились компоненты, стейт-менеджеры (Redux, Vuex). Для многих это стало открытием: «У нас теперь редьюсеры, экшены, стор? Это напоминает бэкенд».

И действительно, Redux во многом перекликается с паттерном CQRS из бэкенда.

2020–2025: Боль монолита Фронт разросся. Сотни компонентов, десятки разработчиков в одном репозитории. Один баг в корзине может случайно задеть шапку сайта. Бэкенд проходил это в начале 2010-х.

2025+ (сейчас и завтра): Микрофронтенды Появилось движение в сторону микрофронтендов — прямого аналога микросервисов. Module Federation, Single-Spa. Каждая команда может владеть своим куском интерфейса, своим стором, своим роутингом.

Наблюдение: Фронтенд идёт по пути, который бэкенд уже прошёл. И знание бэкенд-архитектур помогает не изобретать велосипед.

Часть 3. Три архитектуры, которые пришли из бэкенда во фронтенд

Когда я работал на бэкенде, я использовал луковую, плагинную и событийную архитектуры. Позже я заметил те же паттерны во фронтенде — иногда под другими названиями, но с той же сутью.

1. Луковая архитектура (Onion / Hexagonal / Clean Architecture)

Как это применялось на бэкенде: В центре — бизнес-логика (сущности). Она ничего не знает про базу данных, API или внешние сервисы. Вокруг располагаются слои (сервисы, репозитории, контроллеры). Зависимости направлены внутрь.

Как это выглядит на фронтенде: В центре — модели и чистая бизнес-логика (функции расчёта скидки, валидации, правил). Они ничего не знают про fetch, localStorage или useState.

Далее идёт слой сервисов (API-клиенты, сервисы для работы с хранилищем). Затем слой адаптеров (хуки, преобразующие данные для UI). И самый внешний слой — компоненты React/Vue.

В чём польза: Можно переписать React на Vue — бизнес-логика останется нетронутой. Можно сменить REST на GraphQL — достаточно обновить только слой сервисов. Компоненты не зависят от того, откуда пришли данные.

Признак, что подход используется: В коде есть область domain/ или entities/, которая не импортирует ничего из react или axios.

2. Плагинная архитектура (Plugin / Modular / Microkernel)

Как это применялось на бэкенде: Есть ядро системы (аутентификация, роутинг, базовые сущности).

Остальной функционал — плагины. Плагины регистрируются в ядре и расширяют его, не меняя код ядра. Примеры: Eclipse, VS Code, многие CMS.

Как это выглядит на фронтенде:

Micro Frontends: Каждый микрофронт работает как плагин. Основное приложение (шелл) не знает деталей того, какой плагин подгрузится;

Webpack Module Federation: Один модуль может предоставить свой компонент как плагин для другого.

Плагины для сборщиков: Babel, ESLint, Webpack сами построены на плагинной архитектуре.

В чём польза: Разные команды могут работать над корзиной и каталогом, не затрагивая код друг друга. Можно отключить плагин «Отзывы» — приложение продолжит работать.

Признак, что подход используется: В проекте есть область plugins/, где каждый плагин самостоятельно регистрирует свои маршруты и редьюсеры в ядре через метод register().

3. Событийная архитектура (Event-Driven / Event Sourcing / PubSub)

Как это применялось на бэкенде: Вместо прямого изменения записи в базе данных создаётся событие: «Корзина добавлена», «Заказ оплачен». Другие сервисы подписываются на эти события. База данных может быть просто накопленным потоком событий (Event Store).

Как это выглядит на фронтенде:

Redux / Vuex: Экшены — это события. Редьюсеры — это подписчики;

EventBus в Vue: Механизм публикации и подписки;

RxJS (Subject/BehaviorSubject): Гибкая событийная шина; — Состояние приложения: Один компонент сообщает «Пользователь кликнул». Другой компонент (глубоко в дереве) реагирует на это.

В чём польза: Компоненты не нуждаются в прямом знании друг о друге. Кнопка публикует событие cart:add. Счётчик в углу подписан на него. Хук аналитики — тоже подписан. Если позже потребуется добавить звук при добавлении товара — можно подписать ещё одного слушателя. Ничего не ломается.

В проекте нет многоуровневой передачи пропсов (prop drilling). Компоненты общаются через события или глобальный стор, а не через прямые ссылки друг на друга.

Часть 4. В чём специфика фронтенда

Может возникнуть возражение: «Фронтенд — это UI, здесь другие приоритеты: 16 мс на кадр, реактивность, работа с DOM».

Действительно, специфика есть. Но:

Бизнес-логика (расчёт налога, валидация формы, права доступа) не привязана к DOM;

Связность модулей одинаково вредна и на бэкенде, и на фронтенде;

Тестирование сложной логики проще, когда она находится в чистой функции, а не внутри useEffect.

Фронтенд имеет свои особенности (асинхронность, отрисовка, Event Loop). Но это не отменяет ценности продуманной архитектуры.

Сейчас можно встретить компоненты, внутри которых одновременно происходят запросы, работа с состоянием, чтение из localStorage и показ уведомлений. Это напоминает состояние бэкенда середины 2000-х. И у бэкенда уже есть опыт, как из этого выходить.

Заключение. Что можно взять на заметку

Несколько мыслей в завершение:

1. Знакомство с бэкенд-архитектурами полезно. Не для того, чтобы стать бэкендером, а чтобы увидеть проверенные временем решения. «Чистая архитектура» Роберта Мартина или идеи Domain-Driven Design применимы и на фронте;

2. Разделение слоёв снижает риск. Бизнес-логика, работа с данными и отображение могут жить отдельно. Это делает код более предсказуемым;

3. Событийный подход упрощает коммуникацию между компонентами. Redux, RxJS или EventBus помогают избежать длинных цепочек пропсов;

4. Микрофронтенды — это не просто модный термин. Это реакция на те же проблемы масштабирования, с которыми бэкенд столкнулся десять лет назад.

Когда кто-то говорит «у фронта свой путь, это не бэкенд», в этом есть доля правды. Но во многих вопросах — управлении сложностью, тестируемости, разделении ответственности — путь оказывается общим.

Бэкенд прошёл эту дорогу. Фронтенд идёт по ней сейчас. И иногда полезно посмотреть на карту, которую уже составили те, кто шёл впереди.

Ссылка на оригинальную статью:

Начать дискуссию