Мы придерживаемся концепции smart/dump components Дэна Абрамова.
В /components
лежат только dump components, они ответственны за визуальное отображение и вёрстку компонента. Могут содержать очень простую визуальную функциональность (напр. переключение стэйта открытой модалки). Они все наследуются от React.PureComponent
и имеют stories в storybooks. У некоторых есть тесты, но в основном они тестят правильную передачу props
.
Smart containers могут лежать только в модулях, они ответственны за всю функциональность - получение и отправка данных, sanitize в редакторе, функциональность создания содержания в литературе. У них у всех есть тесты и редко могут быть сторибуки.
Всё просто:
components
— dump componentscomponents/discours-ui-kit
— Наш UI Kit. Сюда пишем все маленькие, очень часто реиспользуемые элементы интерфейса.components/modals
— Уже готовые модальные окна, используемые на сайте. Компонент должен экспортироватьButton
, при нажатии на который будет открываться модальное окно.components/formatters
— Маленькие компоненты, которые просто помогают форматировать вывод. Такие как вывод дат, цифр, валют и так далее. Необходимы для того, чтобы форматы отображения сущностей были едины.
config
— конфигурация приложенияcontexts
— provider'ы и hoc'и, использующие React.Contexti18n
—.pot
и.po
файлы приложения, то есть превод приложения на разные языкиlayouts
— (модули) глобальные шаблоны приложения, содержащие в себе общую структуру сайта: шапку, подвал, а также инициализация всех глобальных контекстов из папкиcontext
modals
- (модули) глобальные модальные окна, реиспользуемые в приложении. Экспортируют кнопку, при нажатии на которую, открывается модальное окно.pages
— (модули) всех страниц и глобальный роутерservices
— сервисы для взаимодействия с внешними источниками данных (API's)styles
— глобальные стили (стараемся избегать) и темыutils
— небольшие функции для переиспользования в приложении
Модулем мы называем отдельный блок готовой части сайта (части лэйаута или страницы). Модули могут находится в папке /layouts
и /pages
.
Каждый модуль это папка, содержащая в себя папки /components
и /containers
. Туда мы складываем все компоненты, которые существуют только в рамках этого модуля, и все контейнеры, что необходимы компонентам.
Например, возьмём модуль src/layouts/Footer
. Из Footer
мы решили выделить компонент FooterBottom
, а там решили выделить FooterSubscribeForm
, которому необходим контейнер для отправки данных в mailchimp. Модуль будет содержать следующую структуру:
Footer/
Footer/components/FooterBottom/
Footer/components/FooterSubscribeForm
Footer/containers/FooterSubscribeForm
Каждая папка компонента должна содержать .stories
для более удобной разработки. В самой папке Footer
так же должен быть .stories
, чтобы можно было увидеть весь модуль собранным вместе.
Такой подход к организации структуры проекта даёт нам простую возможность поделить код сайта на bundle'ы по страницам сайта и подгружать их ассинхронно перед открытием страницы.
Некоторые считают, что лучше делать модули рекурсивными. То есть каждый компонент внутри module может так же иметь папки components
и container
для компонентов, что нужны только внутри компонента внутри module.
В нашем примере это выглядело бы так:
Footer/
Footer/components/FooterBottom/
Footer/components/FooterBottom/components/FooterSubscribeForm
Footer/components/FooterBottom/containers/FooterSubscribeForm
При таком подходе никогда не придется импортировать через ../
, а так же!! сразу видно наследование компонентов, что хорошо.
Но при таком подходе невозможно сразу оценить глазами размер модуля (ибо каждая папка еще может содержать папки). Да и длина путей до файлов начинает пугать.
Поэтому мы решили отказаться от данной идеи.