Перейти к основному содержимому

Слои

Слои - это первый уровень организационной иерархии в Feature-Sliced Design. Их цель - разделить код на основе того, сколько ответственности ему требуется и от скольких других модулей в приложении он зависит.

На этой странице модуль означает внутренний модуль в приложении - файл или каталог с индексным файлом. Не путать с npm-пакетами.

Каждый слой несет в себе особый семантический смысл, помогающий определить, какую ответственность следует возложить на модуль в вашем коде. Названия и значения слоёв стандартизированы для всех проектов, построенных с использованием Feature-Sliced Design.

Всего существует 7 слоёв, расположенных от наибольшей ответственности и зависимости к наименьшей:

Дерево файловой системы с одной корневой папкой src и семью подпапками: app, processes, pages, widgets, features, entities, shared. Папка processes отображена немного тускло. Дерево файловой системы с одной корневой папкой src и семью подпапками: app, processes, pages, widgets, features, entities, shared. Папка processes отображена немного тускло.
  1. App (Приложение)
  2. Processes (Процессы, устаревший слой)
  3. Pages (Страницы)
  4. Widgets (Виджеты)
  5. Features (Фичи/функции)
  6. Entities (Сущности)
  7. Shared (Общий)

Вы не обязаны использовать все слои в своем проекте - добавляйте только те, что приносят пользу вашему проекту.

Правило импортов для слоёв

Слои состоят из слайсов — сильно сцепленных групп модулей. Feature-Sliced Design поддерживает низкую связанность, поэтому зависимости между слайсами регулируются правилом импортов для слоёв:

Модуль в слайсе может импортировать другие слайсы только в том случае, если они расположены на слоях строго ниже.

Например, в ~/features/aaa, слайсом является aaa, поэтому файл ~/features/aaa/api/request.ts не может импортировать код ни из какого модуля в папку из ~/features/bbb, но может импортировать код из ~/entities и ~/shared, а также из соседних модулей в ~/features/aaa.

Определения слоёв

Shared

Изолированные модули, компоненты и абстракции, отдельные от специфики проекта или бизнеса. Внимание: не следует использовать этот слой как свалку утилит!

Этот слой, в отличие от других, состоит не из слайсов, а непосредственно из сегментов.

Примеры содержимого:

  • UI-библиотека
  • API-клиент
  • Код, работающий с API браузера

Entities

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

Каждый слайс этого слоя содержит статические элементы пользовательского интерфейса, хранилища данных и операции CRUD (создание-чтение-изменение-удаление).

Примеры слайсов:

Для социальной сети Для Git-фронтенда (например, GitHub)
  • Пользователь
  • Публикация
  • Группа
  • Репозиторий
  • Файл
  • Коммит

Вы можете заметить в примере фронтенда для Git, что репозиторий содержит файлы. Это делает репозиторий сущностью более высокого уровня, внутри которой вложены другие сущности. Это частая ситуация с сущностями, и иногда трудно иметь такие сущности высокого уровня, не нарушая правило импортов для слоёв.

Вот несколько предложений по решению этой проблемы:

  • UI сущностей должен содержать слоты для мест, куда будут вставляться сущности нижнего уровня
  • Бизнес-логика, связанная с взаимодействием сущностей, должна быть размещена в Features (в большинстве случаев)
  • Интерфейсы сущностей из базы данных могут быть извлечены в слой Shared, рядом с API-клиентом

Features

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

Слайс на этом слое может содержать интерактивные элементы пользовательского интерфейса, внутреннее состояние и запросы к API, которые позволяют выполнять действия, создающие ценность.

Примеры слайсов:

Для социальной сети Для Git-фронтенда (например, GitHub) Действия от имени пользователя
  • Авторизоваться
  • Создать публикацию
  • Вступить в группу
  • Изменить файл
  • Оставить комментарий
  • Слить ветки
  • Автоматически включить тёмную тему
  • Выполнить вычисления в фоне
  • Действия на основе User-Agent

Widgets

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

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

Иногда удобнее разместить бизнес-логику на этом слое. Зачастую, это происходит тогда, когда виджет имеет довольно много интерактивности (например, интерактивные таблицы) и бизнес-логика в нём не переиспользуется.

Примеры слайсов:

Для социальной сети Для Git-фронтенда (например, GitHub)
  • Карточка публикации
  • Шапка профиля пользователя (с действиями)
  • Список файлов в репозитории (с действиями)
  • Комментарий в ветке комментариев
  • Карточка репозитория

Если вы используете вложенную систему маршрутизации (например, роутер Remix), может быть полезно использовать слой Widgets аналогично слою Pages в плоской системе маршрутизации - для создания полноценных интерфейсных блоков с получением соответствующих данных с бэкенда, состояниями загрузки и ограничителями ошибок. Также здесь можно разместить лейауты для слоя Pages.

Pages

Полноценные страницы для страничных приложений (например, веб-сайтов) или экраны/активности для экранных приложений (например, мобильных приложений).

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

Примеры слайсов:

Для социальной сети Для Git-фронтенда (например, GitHub)
  • Лента новостей
  • Страница сообщества
  • Публичный профиль пользователя
  • Страница репозитория
  • Репозитории пользователя
  • Ветки в репозитории

Processes

Этот слой считается устаревшим. Текущая версия спецификации рекомендует избегать его и перемещать его содержимое в features и app.

Выход из ситуаций, когда требуется сложное многостраничное взаимодействие.

Этот уровень намеренно оставлен не очень определенным. Большинству приложений этот слой не пригодится, логику на уровне роутера и сервера следует оставить на уровне App. Рассмотрите возможность использования этого слоя только тогда, когда слой App вырастет настолько, что станет неподдерживаемым и потребует разгрузки.

App

Всё, что касается всего приложения, как в техническом смысле (например, провайдеры контекста), так и в бизнес-смысле (например, аналитика).

Этот слой обычно не содержит слайсов, как и Shared, вместо этого он содержит непосредственно сегменты.

Примеры содержимого:

  • Стили
  • Роутер
  • Хранилища данных и прочие провайдеры контекста
  • Инициализация аналитики