Что из себя представляет страница в архитектуре FSD?
Комментарии (2)
Ответ сгенерирован нейросетью и может содержать ошибки
Что такое страница (Page) в архитектуре Feature-Sliced Design (FSD)
В методологии Feature-Sliced Design (FSD) страница (page) — это самостоятельный, полноценный модуль верхнего уровня, который отвечает за композицию фич, виджетов и сущностей в готовый пользовательский интерфейс для определённого маршрута (URL). Страницы находятся на самом верхнем слое архитектуры (apps, pages или app/pages в зависимости от версии FSD) и служат точкой входа для рендеринга конкретного экрана приложения.
Ключевые характеристики страницы в FSD
- Маршрутизация: Каждая страница напрямую связана с определённым маршрутом (роутом) в приложении. Например, страница
ArticlePageбудет отвечать за путь/articles/:id. - Композиция, а не логика: Основная задача страницы — собрать (скомпоновать) независимые блоки из нижних слоёв (feature, entity, shared). Страница сама по себе не должна содержать сложную бизнес-логику или состояние, выходящее за рамки управления композицией.
- Минимальная сложность: Идеальная страница — это тонкий слой, который импортирует компоненты, передаёт им необходимые данные (часто через props) и рендерит их в правильном порядке. Вся бизнес-логика вынесена в фичи (features), а переиспользуемая UI-логика — в виджеты (widgets).
- Публичный API: Страницы являются частью публичного API слоя и могут свободно импортировать модули из любых нижних слоёв (соблюдая правило зависимостей
pages -> features -> entities -> shared).
Пример структуры и кода
Рассмотрим структуру проекта и пример кода для страницы просмотра статьи.
Структура папок (по методологии FSD v2):
src/
├── pages/ # Слой страниц
│ └── article-details/ # Слайс (папка) страницы
│ ├── ui/ # UI-компоненты, специфичные для этой страницы
│ │ └── ArticleDetailsPage.tsx
│ └── index.ts # Публичный API (реэкспорт)
├── features/ # Слой фич
│ └── add-comment/ # Фича "Добавление комментария"
│ ├── model/ # Логика (стор, эффекты)
│ ├── ui/ # Компоненты фичи
│ └── lib/ # Вспомогательная логика
├── entities/ # Слой сущностей
│ ├── article/ # Сущность "Статья"
│ └── comment/ # Сущность "Комментарий"
├── shared/ # Переиспользуемый слой
│ ├── ui/ # UI-кит (Button, Card, etc.)
│ └── api/ # Инфраструктура API
└── app/ # Инициализация приложения (роутинг, провайдеры)
Код страницы ArticleDetailsPage:
// src/pages/article-details/ui/ArticleDetailsPage.tsx
import { ArticleDetails } from '@/entities/article';
import { CommentList } from '@/entities/comment';
import { AddCommentForm } from '@/features/add-comment';
import { ArticleRecommendationsList } from '@/features/article-recommendations-list';
import { Page } from '@/shared/ui/page';
import { VStack } from '@/shared/ui/stack';
import { useParams } from 'react-router-dom';
export const ArticleDetailsPage = () => {
const { id } = useParams<{ id: string }>(); // Получаем ID из URL
if (!id) {
return <div>Статья не найдена</div>;
}
// Страница только компонует блоки, не содержит своей логики
return (
<Page>
<VStack gap="32" max>
{/* Сущность: отображение данных статьи */}
<ArticleDetails articleId={id} />
{/* Виджет или фича: рекомендации */}
<ArticleRecommendationsList />
{/* Фича: форма добавления комментария */}
<AddCommentForm articleId={id} />
{/* Сущность: список комментариев */}
<CommentList articleId={id} />
</VStack>
</Page>
);
};
Роль и преимущества такого подхода
- Чёткое разделение ответственности: Страница отвечает только за макет и композицию для конкретного маршрута. Это делает её простой для понимания и модификации.
- Максимальная переиспользуемость: Поскольку вся логика живёт в фичах и сущностях, их можно использовать на разных страницах. Например,
AddCommentFormможет быть использован и на странице блога, и на странице продукта. - Упрощённая навигация и code-splitting: Каждая страница естественным образом становится точкой для ленивой подгрузки (lazy loading). Роутер приложения может динамически импортировать только нужную страницу, что улучшает производительность.
- Масштабируемость: Добавление нового экрана (маршрута) сводится к созданию новой папки в слое
pagesи композиции существующих модулей. Это предсказуемо и не приводит к росту энтропии в коде. - Ориентация на пользовательские сценарии: Страница — это целостный пользовательский сценарий (просмотр товара, оформление заказа), что совпадает с восприятием продукта менеджерами и дизайнерами, упрощая коммуникацию в команде.
Отличие от других слоёв
- Страница (Page) vs Фича (Feature): Фича инкапсулирует конкретную возможность пользователя (добавить в корзину, лайкнуть, отфильтровать). Страница же собирает несколько фич в законченный экран. Фича может использоваться на многих страницах.
- Страница (Page) vs Виджет (Widget): Виджет — это сложный композитный компонент с собственной, часто кросс-фичёвой, логикой отображения (например,
Sidebarс навигацией и рекламным баннером). Виджет тоже можно использовать на разных страницах, но страница — это всегда конечный, привязанный к URL экран.
Таким образом, страница в FSD — это конечная точка сборки интерфейса, отвечающая за компоновку независимых, переиспользуемых модулей в соответствии с бизнес-маршрутом, что обеспечивает чистоту, масштабируемость и поддерживаемость кода крупных frontend-приложений.