Gernar
Архитектура и принципы кода

Как строил архитектуру до Feature-Sliced Design

Разбор вопроса «Как строил архитектуру до Feature-Sliced Design» для Frontend Developer: что проверяет интервьюер, ключевые тезисы, практические примеры и частые ошибки.

Вопрос

Как строил архитектуру до Feature-Sliced Design

Профессия

Frontend Developer

Что хочет услышать интервьюер

Интервьюер хочет услышать, какие подходы к архитектуре использовались до FSD, какие проблемы они вызывали и как кандидат пришел к пониманию необходимости более структурированного подхода. Важно показать осознание недостатков предыдущих решений.

Ключевые тезисы

  • Использовал классический подход по слоям (presentation, business logic, data access), но это часто приводило к сложностям при масштабировании.
  • Применял группировку по типам файлов (components, containers, reducers, actions), что усложняло навигацию по проекту с ростом кодовой базы.
  • Пробовал модульную структуру, где каждый модуль содержал свою логику, но это создавало дублирование кода и сложности в переиспользовании.
  • Иногда использовал подход, основанный на маршрутах (route-based), где каждая страница имела свою папку с компонентами и логикой, но это не решало проблему shared-логики.

Подробный ответ

До знакомства с Feature-Sliced Design (FSD) я экспериментировал с разными подходами к организации кодовой базы. Классический слоеный подход (presentation, business logic, data access) казался логичным, но на практике приводил к размазыванию связанной логики по разным папкам. Например, работа с пользователем требовала правок в компонентах, редьюсерах и API-модулях одновременно. Группировка по типам файлов (components/, containers/, reducers/) усугубляла проблему — при добавлении новой фичи приходилось создавать файлы в разных местах, что снижало локализацию изменений. Модульная структура (по бизнес-сущностям) улучшала ситуацию, но порождала дублирование — например, компонент Modal использовался в нескольких модулях, но его логика копировалась. Route-based подход упрощал разработку конкретных страниц, но общие компоненты (например, Header) становились «сиротами», а их модификация требовала правок в десятках мест.

Практические примеры

Пример 1

Пример классического слоеного подхода: папка src/reducers/userReducer.js содержала логику, которая использовалась в src/components/UserProfile.jsx и src/api/userService.js. При изменении требований к авторизации приходилось синхронно править 3 файла в разных слоях.

Пример 2

Пример дублирования в модульной структуре: в модулях Dashboard и AdminPanel были свои версии usePagination с 90% совпадающим кодом. Проблема обнаружилась только при необходимости добавить новую фичу в пагинацию.

Пример 3

Route-based подход в проекте с 50+ страницами: общий хук useAuth лежал в src/pages/Login/utils/, хотя использовался на 20 страницах. Это приводило к неочевидным зависимостям и циклическим импортам.

Частые ошибки

  • Смешивание подходов без четких правил (например, часть компонентов в components/, а часть — в модульных папках), что создавало хаос в импортах.
  • Игнорирование circular dependencies при route-based подходе, когда страницы начинают импортировать утилиты друг у друга.
  • Преждевременная оптимизация архитектуры — например, создание абстрактных «общих» модулей до появления реальных случаев переиспользования.

Связанные темы

  • Принцип локализации изменений (Co-location)
  • Методологии проектирования архитектуры: DDD (Domain-Driven Design), Clean Architecture
  • Инструменты анализа зависимостей: Madge, Dependency-Cruiser
  • Паттерны повторного использования кода: HOC, Render Props, Custom Hooks

Follow-up вопросы

Какие конкретные проблемы возникали при использовании классического подхода по слоям?

Уровень: basic

Основные проблемы — жесткая связность слоев, сложности при рефакторинге бизнес-логики и дублирование кода между слоями. Например, изменения в API требовали правок в нескольких местах.

Как вы решали проблему дублирования кода при модульной структуре?

Уровень: intermediate

Пытался выносить общую логику в отдельные утилиты или создавал shared-модули, но это часто приводило к избыточным зависимостям и усложняло тестирование.

Какие инструменты или практики помогали вам управлять сложностью route-based подхода?

Уровень: intermediate

Использовал динамический импорт компонентов для ленивой загрузки и контексты React для shared-логики. Однако это не решало проблему согласованности состояния между страницами.

Как вы оценивали эффективность своих архитектурных решений до перехода на FSD?

Уровень: advanced

Анализировал метрики (время сборки, количество пересборок), сложность добавления новых фич и частоту регрессионных багов. Также учитывал feedback команды.

Были ли случаи, когда вы комбинировали несколько подходов в одном проекте? Как это работало?

Уровень: advanced

Да, например, совмещал route-based для страниц и модульный для виджетов. Это создавало хаос в проекте, так как правила организации кода становились неочевидными.

Содержание