Каждый разработчик рано или поздно сталкивается с вопросом: как организовать проект так, чтобы он не превратился в хаос? Или как исправить проект, в котором уже царит хаос?
Начинается всё одинаково: мы делаем простое MVP или проект с ограниченным функционалом, не заморачиваемся по поводу архитектуры и организации кода, ведь проект небольшой и несложный, а сделать его нужно уже здесь и сейчас. Но время идёт, и у бизнеса появляются всё новые требования. Какие‑то изначальные идеи полностью отменяются или меняются до неузнаваемости, разрастается команда, дизайн меняется несколько раз, появляется необходимость покрыть проект тестами, а иногда и необходимость вообще сменить стек технологий. И вот вы уже работаете над кодом, в котором становится всё сложнее вносить изменения в существующий функционал. Всё держится на костылях, становится трудно ориентироваться в куче файлов, и кажется, что всё устроено как‑то не так, как должно быть.
В этот момент мы начинаем задаваться вопросом: «а как нужно писать и организовывать код на самом деле?». В поисках ответа мы читаем статьи, смотрим обучающие видео, доклады и неизбежно натыкаемся на Feature‑Sliced Design (FSD).
Знакомство с FSD
Первое знакомство с FSD выглядит многообещающе. На первый взгляд, это готовая система, способная устранить хаос и привести проект к порядку. Более того, в сообществе FSD нередко называют «лучшей архитектурой для фронтенда», что создаёт определенные ожидания.
Однако на практике всё оказывается не так радужно. Многие из тех кто внедряет FSD на более‑менее крупных проектах, сталкиваются с подобными проблемами:
возникают вопросы о том, какую вложенность виджетов можно считать допустимой
некоторые фичи оказываются настолько «размазаны», что с ними становится сложно работать — чтобы понять или изменить одно флоу, приходится постоянно переключаться между кучей папок и файлов
проблемы с чётким делением сущностей и постоянные разночтения правил
Изучая опыт команд на конференциях и в статьях, можно обнаружить, что многие команды адаптируют FSD на своё усмотрение, отходя от канонического варианта. Часто докладчик начинал свою речь с признания в духе: «Сначала мы неправильно поняли методологию» или «Нам пришлось адаптировать её под себя».
Как оказалось, сами авторы FSD признают эти трудности. Например, в версии 2.1 акцент сместился к «pages‑first», с обоснованием, что предыдущий подход заставлял разработчиков «прыгать по папкам» для изменения одного пользовательского сценария и требовал глубокого понимания бизнес‑контекста, что создавало почву для конфликтов и недопониманий между членами команды. Так что переход к «pages‑first» сделал методологию более интуитивной.
Но возникает закономерный вопрос: если подход требует такой адаптации под каждую команду и каждый проект, то действительно ли он решает одну из основных задач — обеспечение единообразия и предсказуемости?
И здесь мы сталкиваемся с фундаментальной проблемой любой системы: стремление к универсальности неизбежно конфликтует с реальным разнообразием. FSD пытается стандартизировать то, что по своей природе контекстно‑зависимо. И на мой взгляд, сама необходимость в постоянных адаптациях указывает не столько на недостатки, сколько на невозможность создания универсального решения.
Каждая «своя» интерпретация FSD это на самом деле попытка примирить абстрактные правила с конкретными реалиями проекта. Возможно, ценность FSD не в готовых ответах, а в том, что он заставляет команды осознанно подходить к организации кода, даже если конечный результат отличается от некоего канонического, при этом давая скелет, на который можно опереться. И если подходить к этому так, то FSD работает как своеобразный катализатор размышления о нужной конкретно вам системе, а не как жёсткий свод правил.
Тем не менее, остаются вопросы, которые FSD принципиально не решает: как проектировать бизнес‑логику, организовывать управление состоянием, выстраивать взаимодействие с API, обрабатывать ошибки и крайние случаи. А без ответов на эти вопросы любой проект рано или поздно станет трудноподдерживаемым.
Да, FSD частично отвечает на эти вопросы. Как пример, рекомендует отделять бизнес‑логику от UI, помогает разделять части приложения и так далее, однако не даёт конкретных рекомендаций о внутренней реализацией этих частей.
Подмена понятий
Часто в сообществе FSD называют «архитектурой», что создает неправильные ожидания от решения проблем архитектурного характера. И это представление потенциально опасно.
Мы подменяем сложную, абстрактную и невидимую работу по проектированию системы на простую, конкретную и видимую, раскладывая слои по папкам. Эта подмена понятий может привести к тому, что команда считает, что, внедрив FSD, она «занялась архитектурой», и перестает задавать себе по‑настоящему важные архитектурные вопросы. А эти вопросы никуда не исчезают.
На первый взгляд может показаться, что различие между архитектурой и организацией кода и так очевидно и не стоит отдельного обсуждения. Однако вся эта путаница не придумана из головы на пустом месте, а реально существует в нашем сообществе.
Что такое архитектура на самом деле?
Архитектура — это высокоуровневая структура системы, определяющая принципы взаимодействия компонентов и потока данных. Архитектура отвечает на такие вопросы:
Как данные проходят через систему?
Как разделяются ответственности между частями системы?
Какие принципы используются для работы с состоянием и ошибками?
Какие паттерны и принципы используются для изоляции бизнес‑логики от фреймворков и внешних сервисов?
И в то же время существует такое понятие как методология организации кода — это набор правил о том, как структурировать файлы и папки, как их называть, где что размещать, какие правила импортов соблюдать. То есть в отличие от архитектуры, методология организации кода не определяет, как работает приложение в целом, а задаёт правила порядка и структуры.
Поэтому в этом смысле FSD не является архитектурой, хотя и затрагивает некоторые ее аспекты. Это методология организации кода, потому что она предлагает определенную структуру файлов и правила их взаимодействия, но не определяет, как ваше приложение будет работать на высоком уровне.
Из‑за этого также кажутся странными претензии некоторых людей, что «зачем использовать FSD, если есть Clean Architecture», как бы противопоставляя эти понятия, хотя в реальности это разные вещи, решающие разные проблемы. На практике для полноценного проекта нужно сочетать и архитектурные, и организационные, и множество других технических решений.
Даже при соблюдении всех рекомендаций FSD легко получить:
Плохое управление состоянием (например, прямые мутации состояния через UI)
Неоптимизированную работу с API (дублирование запросов в разных фичах и виджетах)
Плохую систему обработки ошибок и крайних случаев (отсутствие централизованной обработки)
Смешение ответственности
Сложности с тестированием
Но это не проблема или недостаток FSD. Проблема возникает, когда от организационной методологии ожидают решения всех технических проблем проекта, что сейчас мы это внедрим и будет «конфетка».
Более того, нет какой‑то одной волшебной архитектуры или библиотеки, которая решит все проблемы, это всегда должна быть комбинация разных подходов для разных задач.
Не существует универсальных решений. Не нужно искать «лучшую архитектуру для фронтенда». Нам нужно научиться задавать правильные вопросы: не «как правильно организовать код?», а «какие проблемы мы пытаемся решить и какие инструменты для этого подходят?». FSD может быть частью ответа, но никогда не будет полным ответом.