Pull to refresh

Comments 20

А как оказывается из примеров на сайте feature sliced design - todo app'ы. На udemy смотрел такие курсы "сайт кинофильмов за 4 часа".

Здравствуйте, не совсем понял суть комментария, не могли бы вы более подробно описать?

В простых приложениях, например Todo App на React (классика) очень хорошо работают многие паттерны - например можно разбить компоненты на мельчайшие части, прям компоненты по 1 строчке. Т.е. удается добиться максимального Single Responsibility. Однако это не значит что это сработает в продакшене.

Хотелось бы по продакшеннее примера Feature-Sliced Design.

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

К сожалению, не могу привести пример проектов по соображениям NDA, однако предлагаю вам ознакомиться с примерами реальных проектов, которые предоставлены на официальной странице гитхаба Feature Sliced Design: https://github.com/feature-sliced/examples (эти примеры и много другое также можно найти по ссылке с доп. информацией в конце статьи https://github.com/egorchh/Feature-Sliced-Design-information#примеры)

Также вы можете ознакомиться с моим пет-проектом. Крупное приложение построенное на FSD - https://github.com/egorchh/production-project. (можно удобно запустить на своем пк)

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

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

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

Как менеджер по продажам. "У нас в фирме качество." А что за качество, что там - непонятно.

Цель статьи не прорекламировать FSD, а рассказать о ней, описать минусы и плюсы. Использовать ее или нет - решение каждого разработчика.

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

Здравствуйте! Спасибо за статью!

Сейчас внедряю fsd в проект среднего размера. Столкнулся с такой дилеммой, есть глобальный стор, zustand, но непонятно где его держать, если не а app.

Состояние приложения, настройки и тд, должны шарится по всем уровням. Но тогда нарушается направление зависимостей.

В вашем примере я заметил провайдер в app. Возможно даже redux, как вы реализуете механизм глобального состояния в контексте fsd?

Здравствуйте, поскольку не работал с Zustand, приведу пример на Redux Toolkit. Думаю, логика будет идентична.

1 шаг:

Поскольку на все приложение один глобальный стор, его стоит объявить и конфигурировать в app. На скрине ниже: конфигурируем store в одноименном файле, также к конфигурации относится не только объявление стора, но и глобальные типы, дополнительные инструменты. В сегменте ui создаем hoc с оберткой (hoc тут необязательный, можем просто обернуть компонент в провайдер). StoreProvider импортируем из app, оборачиваем в него корневой компонент. Корневой компонент находится все слоев, можно представить его выше слоя app по иерархии (такое исключение из правил).

Структура слоя app
Структура слоя app
StoreProvider.tsx
StoreProvider.tsx
Корневой файл приложения, обернутый в StoreProvider
Корневой файл приложения, обернутый в StoreProvider

2 шаг:

Нам нужно работать с глобальным стейтом в компонентах, которые находятся ниже по иерархии слоев:

Посмотрим на примере фичи:

В рамках приведенной ниже фичи, мы создаем слайс loginSlice, селекторы, если необходимо, asynThunk'и, типы. Все эти сущности относятся только к работе с той частью стора, которая напрямую связана с фичей

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

features/AuthByUsername
features/AuthByUsername
Схема работы с глобальным стейтом
Схема работы с глобальным стейтом

Надеюсь, что сумел раскрыть суть подхода, если будут вопросы, с радостью расскажу более подробно.

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

Но допустим мы хотим в глобальном сторе создать сущность counters. Это счётчики которые должны быть доступны в разных местах приложения. Порой один счётчик в нескольких вью или страницах. Эти самые счётчики могут браться из разных entity. Или вообще приходят в отдельном запросе при инициализации приложения.

Или ещё пример. Роутинг. В приложении кроме страниц могут быть разделы у которых уже в свою очередь страницы. Все это должно быть ещё связано с разным боковым меню например. И слой shared не похож на то место которое должно владеть такими данными.

Прошу прощения за долгий ответ, был в отпуске.

Насколько я понял примеры:

1) Пусть в глобальном сторе у нас будут счетчики. Под каждый счетчик мы можем создать свою сущность или сделать единую изменяемую сущность счетчика (в зависимости от того, насколько они отличаются друг от друга). В этой сущности (слой entity) мы как раз будем обрабатывать запрос приходящий с сервера или работать с счетчиками через клиент и посылать данные об их изменении в глобальный стор. А в нужных нам местах брать информацию о счетчиках из глобального стора.

Таким образом мы можем посылать данные в стор и забирать их оттуда без нарушения потока данных. Поскольку, хоть инициализация стора и хранится в слое app, сам по себе стор распростаняется на все приложение.

2) К сожалению, не совсем понял пример. Роут-конфиг (скрин ниже) также хранится в слое app. В нашем выпадающем меню, которое, |скорее всего является виджетом, каждый элемент - ссылка <Link/>

Кликаем по ссылке, перемещается по нужному роуту.

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

А можно использовать feautures/todos/api в features/todos/ui ? Или api можно использовать только на слой ниже?

Прошу прощения за долгий ответ, был в отпуске.

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

Спасибо за ответ)
А еще не подскажите, как можно реализовать правильно redux или mobx в проекте?
Просто там возникают зависимости сильные и получается что все приходится тащить в shared

Я такой вопрос задавал уже, но там не чего внятного не ответили, только через костыль, может быть вы чего подскажите?)
https://qna.habr.com/q/1302414

Вот в этом комментарии отвечал на схожий вопрос (https://habr.com/ru/companies/avito/articles/752536/comments/#comment_25853686), если из этого ответа будет не до конца понятно, предлагаю ознакомиться с этим проектом (https://github.com/egorchh/production-project). Если ясней не станет, то отпишитесь, пожалуйста, я попробую расписать максимально подробный ответ.

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

const useAppDispatch и useAppSelector, они ведь экспортируют в себя типы из createConfigure

А useAppDispatch и useAppSelector используются во всем проекте и получается что мы в shared/hooks экспортируем app/provider

Да, к сожалению, это один из кейсов, которые не до конца учтены в методологии. Это можно считать одним из исключений, поскольку, если бы мы задавали useAppDispatch и useAppSelector в слое app, нарушение принципов было бы куда серьезней.

По поводу таких кейсов советую обращаться к ребятам в телеграмм канал, там подскажут компромисное решение. https://t.me/feature_sliced

FSD - рекомендации по написанию кода, так что от них иногда можно отступать. Но не сильно и не часто) Спасибо за замечание!

Sign up to leave a comment.