Не так давно мне поручили помочь команде разработать приложение Redux на основе CRUD. Один из вопросов, который мне задавали, заключался в том, как лучше структурировать проект Redux. В то время как другие фреймворки и языки часто предоставляют рекомендации или лучшие практики, миры Redux и Typescript по-прежнему кажутся Диким Западом, где каждый структурирует проекты по своему усмотрению.

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

Проекты CRUD Redux обычно состоят из:
– глобальных компонентов, которые можно использовать в любом месте приложения
– классов служб/одиночек, которые охватывают жизненный цикл приложения и доступны из любого места в приложении
– Вспомогательные функции/модули
– Глобальное состояние Redux
– Сущности, которые определяют свои собственные локально используемые компоненты/состояния/представления Redux
– Некоторые компоненты начальной загрузки, которые связывают приложение вместе

Их можно организовать в следующую структуру папок:

src/
 components/ /* Global app components */
   index.ts /* Exports components from their folders */
   Button/ /* A folder per component containing both the component implementation and styles */
     Button.tsx
     Button.less
  ...
 bootstrap/ /* Bootstrapping/initialisation components */
  App.tsx
  Header.tsx
  ...
 entities/
   person/
     components/ /* Person-specific components that are used throughout the person/ directory */
       Avatar/ /* Follows the same structure as global components */
         Avatar.tsx
         Avatar.less
     redux/ /* Person specific state */
       types.ts 
       actions.ts
       index.ts /* Exports state + reducer */
       reducer.ts
     views/ /* Person specific views */
       list/
         index.ts /* Exports the component which provides the entry point to the list */
         PersonList.tsx
         PersonListOverlay.tsx
         ...
       add/
         ...
 redux/ /* Global Redux state which binds all the entity-level Redux states together */
   state.ts
   reducer.ts
   index.ts
 
services/
  ApiService.ts
  ...
utilities/
  index.ts /* Exports all utilities */
  math.ts
  string.ts

Хотя это невероятно простая структура, я считаю ее полезной отправной точкой при создании нового приложения. Чтобы расширить это, в качестве примера предположим, что сущности могут содержать подсущности:
- Сущность человека может содержать подсущность «образование»
- Сущности образования не могут существовать без человека

Структура проекта для объекта образования может следовать точно такой же структуре, что и для объекта-человека. Это:

person/ /* Top level entity */
  related/ /* Extra folder containing all sub-entities */
    education/ /* Sub-entity */
      components/ /* Education components used throughout all education views */
      views/ /* Education-specific views */
        list/
        add/
        edit/
      redux/ /* Education-specific Redux files */

В целом, эту структуру проекта можно легко расширить для работы с проектами, не основанными на CRUD и даже на основе Redux. Относитесь к нему как к свободному руководству и изменяйте его в соответствии с потребностями вашего собственного приложения.

Узнайте больше о Томе Шпитмане на tomszpytman.com