← Назад к вопросам

Что находится в слое Shared в FSD?

2.2 Middle🔥 202 комментариев
#JavaScript Core

Комментарии (2)

🐱
deepseek-v3.2PrepBro AI6 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Что находится в слое Shared в методологии Feature-Sliced Design (FSD)?

Shared (Общий) слой — это фундаментальный элемент архитектуры Feature-Sliced Design (FSD), предназначенный для хранения переиспользуемых модулей, которые не привязаны к конкретной бизнес-логике приложения. Его главная цель — обеспечить единообразие и исключить дублирование кода по всему проекту. В отличие от слоёв App, Pages, Widgets, Features и Entities, которые организованы по принципу "близости к пользователю" или бизнес-сущностям, слой Shared служит технической инфраструктурой, поддерживающей работу всех остальных слоёв. Он является самым низкоуровневым в иерархии FSD и не должен зависеть ни от одного вышестоящего слоя.

Ключевые составляющие слоя Shared

Обычно в этот слой включают следующие категории кода:

1. UI-компоненты (UI-Kit)

Базовые, примитивные компоненты интерфейса, которые не содержат бизнес-логики. Они являются строительными блоками для более сложных компонентов в вышележащих слоях.

  • Примеры: Кнопки (Button), поля ввода (Input), модальные окна (Modal), заголовки (Typography), иконки (Icon).
  • Критерий: Компонент должен быть максимально абстрактным и переиспользуемым в различных контекстах. Например, кнопка принимает children, onClick и variant, но не знает о "добавлении товара в корзину".
// shared/ui/Button/Button.tsx
import { ButtonHTMLAttributes, ReactNode } from 'react';
import cls from './Button.module.scss';

interface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
    children: ReactNode;
    variant?: 'primary' | 'secondary' | 'outline';
}

export const Button = ({ children, variant = 'primary', ...props }: ButtonProps) => {
    return (
        <button className={`${cls.button} ${cls[variant]}`} {...props}>
            {children}
        </button>
    );
};

2. Инфраструктурные утилиты и хелперы

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

  • Примеры: Форматирование даты (formatDate), валидация email (isValidEmail), функции для работы с массивами/объектами (debounce, throttle), генерация уникальных ID.
// shared/lib/format/formatDate.ts
export const formatDate = (date: Date, locale: string = 'ru-RU'): string => {
    return new Intl.DateTimeFormat(locale, {
        year: 'numeric',
        month: 'long',
        day: 'numeric',
    }).format(date);
};

3. Конфигурация и константы

Глобальные настройки и неизменяемые значения, используемые в разных частях приложения.

  • Примеры: Конфигурация API (API_URL), ключи для локального хранилища (LOCAL_STORAGE_KEYS), текстовые константы (DEFAULT_PAGE_SIZE), настройки темы (цвета, отступы).
// shared/config/consts.ts
export const API_URL = process.env.REACT_APP_API_URL || 'http://localhost:3000/api';
export const DEFAULT_PAGE_SIZE = 20;
export const LOCAL_STORAGE_KEYS = {
    ACCESS_TOKEN: 'access_token',
    THEME: 'app_theme',
} as const;

4. Типы и интерфейсы (для TypeScript)

Общие типы данных, которые используются в нескольких слоях или фичах.

  • Примеры: Базовые типы (Maybe<T>, PaginatedResponse<T>), интерфейсы для общих DTO (Data Transfer Object), утилитарные типы (ValueOf, Keys).
// shared/types/api.ts
export type PaginatedResponse<T> = {
    items: T[];
    total: number;
    page: number;
    limit: number;
};

export type ApiError = {
    message: string;
    code: number;
};

5. API-инстансы и HTTP-клиенты

Настройка базового клиента для сетевых запросов (например, с помощью axios или fetch).

  • Примеры: Экземпляр axios с интерцепторами для добавления токенов, обработки ошибок, логирования.
// shared/api/apiInstance.ts
import axios from 'axios';
import { API_URL } from '../config/consts';

export const apiInstance = axios.create({
    baseURL: API_URL,
    timeout: 10000,
});

apiInstance.interceptors.request.use((config) => {
    const token = localStorage.getItem('token');
    if (token) {
        config.headers.Authorization = `Bearer ${token}`;
    }
    return config;
});

6. Управление состоянием (глобальные сторы)

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

  • Примеры: Стор для управления темой приложения (ThemeStore), стор для уведомлений/тостов (NotificationStore), стор для загрузки данных приложения (AppLoadStore). Важно: Сторы, относящиеся к бизнес-сущностям (например, UserStore, CartStore), должны находиться в слое Entities.

Принципы и ограничения слоя Shared

  • Запрет на внутренние импорты "сверху": Модули внутри Shared не могут импортировать что-либо из слоёв Entities, Features, Widgets, Pages или App. Это гарантирует его независимость и переиспользуемость.
  • Минимизация бизнес-логики: Код в Shared должен быть максимально агностичным к предметной области. Если модуль начинает знать о "пользователях", "заказах" или "платежах", это верный признак, что его нужно переместить в слой Entities или Features.
  • Высокая степень переиспользования: Если некий код используется только в одном Feature или на одной Page, он, скорее всего, не принадлежит Shared. Его следует разместить ближе к месту использования, соблюдая принцип инверсии зависимостей.
  • Структура внутри слоя: Сам слой Shared также может быть структурирован по технологическому признаку (например, ui/, lib/, api/, config/, types/), а не по бизнес-признаку.

Итог

Таким образом, слой Shared в FSD — это технологический фундамент приложения, его "стандартная библиотека". Он содержит всё, что можно вынести за рамки бизнес-требований: от базовых кнопок и утилит форматирования до конфигурации API и глобальных типов. Его правильная организация критически важна для поддержания чистоты архитектуры, снижения связанности между модулями и обеспечения долгосрочной масштабируемости проекта.

Что находится в слое Shared в FSD? | PrepBro