Расширения FEOD для продвинутых проектов
Расширения для FEOD — это способ адаптации под конкретные подходы и нужды. В отличие от модификаций, они не предполагают альтернативный подход, а просто добавляют возможности или делают правила более строгими.
SSR (Server-Side Rendering)
FEOD изначально спроектирован так, чтобы поддерживать SSR. Для работы с ним есть готовый пример, и, что важно, ключевые отличия кроются в организации приложения.
Вместо единого App мы можем вынести отдельный уровень Server. Туда попадают части, связанные исключительно с сервером и недоступные нигде больше.
В реальности это выражается всего в двух файлах:
entry.server.ts— точка входа сервераentry.client.ts— точка входа клиента
И на этом всё. Такая структура упрощает разделение обязанностей и делает приложение более прозрачным.
Если же мы говорим об использовании готовых фреймворков, то вы можете использовать их встроенные возможности для SSR и не подстраиваться схожим образом.
Пример структуры для SSR
Dependency Injection
В FEOD акцент сделан на минимизацию кросс-модульных взаимодействий в пользу Inversion of Control. Одной из наиболее эффективных реализаций является Dependency Injection. Для этого можно использовать различные инструменты, например SDI (Simple Dependency Injection) или другие полноценные DI-решения.
Подход делает зависимости явными и управляемыми. Это особенно заметно, когда проект разрастается, и поддержка структуры становится критически важной.
Пример использования IoC
// modules/Notifications/index.ts
export interface NotificationService {
showSuccess(message: string): void
showError(message: string): void
}
let notificationService: NotificationService
export function setNotificationService(service: NotificationService) {
notificationService = service
}
export function getNotificationService(): NotificationService {
if (!notificationService) {
throw new Error('Notification service not initialized')
}
return notificationService
}
// app/integrations/notifications.ts
import { setNotificationService } from '@/modules/Notifications'
import { ToastService } from '@/modules/ToastUI'
setNotificationService(new ToastService())
// Использование в любом модуле:
import { getNotificationService } from '@/modules/Notifications'
const notifications = getNotificationService()
notifications.showSuccess('Operation completed successfully')Преимущества IoC в FEOD
- Явные зависимости — легко понять, от чего зависит модуль
- Упрощённое тестирование — можно легко подменить реализации
- Слабая связанность — модули не зависят от конкретных реализаций
- Гибкость — можно менять реализации без изменения модулей
Интеграция с DDD (Domain-Driven Design)
Если в вашей команде много бэкенд-разработчиков и они привыкли мыслить в терминах DDD, FEOD легко подстраивается под этот подход. В модулях можно выделить дополнительные сущности — Entities и Adapters.
Для тех, кто знаком с DDD, назначение этих частей очевидно. Они помогают ещё чётче определять входы и выходы модуля, обеспечивая строгую структуру и понятные границы.
Пример структуры модуля с DDD
Entities в контексте FEOD
Entities в DDD-подходе представляют бизнес-сущности с их поведением. В FEOD они размещаются внутри модуля в папке domain/entities/.
// modules/UserManagement/domain/entities/User.ts
export class User {
constructor(
private id: UserId,
private email: Email,
private profile: UserProfile
) {}
updateEmail(newEmail: Email): void {
this.email = newEmail
}
getId(): UserId {
return this.id
}
}Adapters в контексте FEOD
Adapters обеспечивают взаимодействие модуля с внешним миром:
- Primary adapters (входные) — UI-компоненты, которые используют модуль
- Secondary adapters (выходные) — API-клиенты, репозитории, внешние сервисы
// modules/UserManagement/adapters/secondary/api/userApi.ts
import { User } from '../../domain/entities/User'
export class UserApi {
async fetchUser(id: string): Promise<User> {
// Реализация API-запроса
}
}Такой способ интеграции FEOD особенно полезен для проектов, где требуется дисциплинированная архитектура и чёткое разделение между бизнес-логикой и техническими деталями.
Использование FEOD за пределами фронтенд-приложений
Открытый вопрос: можно ли использовать FEOD за пределами фронтенд-приложений? Например, в разработке инструментов для линтинга, UI-библиотек или любых других пакетов, которые сами по себе не являются фронтенд-приложениями.
Эта идея пока остаётся в стадии обсуждения и проработки. Но направление интересное: если удастся масштабировать FEOD на такие кейсы, мы получим универсальный архитектурный инструмент, применимый гораздо шире, чем просто в рамках интерфейсных проектов.
Потенциальные области применения
- UI-библиотеки — организация компонентов и утилит
- Инструменты разработки — линтеры, плагины, утилиты
- BFF и полноценный бэкенд