Многие руководствуются рекомендациями Presentational and Container Components, но уважаемый автор признаётся в сносках, что концепция разделения спорная, и компоненты можно смешивать. А если это так, то зачем тащить чемодан без ручки? Все компоненты проекта удобнее хранить в одной общей папке. Какие плюсы:
  • Простота навигации по файловой системе.
  • Уникальные имена компонентов проекта.
  • Импорт без боли ('../../../../../..').


Когда проект вырастет, следует дробить его на приватные npm-пакеты, инкапсулируя реализацию. Но не выращивать дерево подпапок внутри папки компонентов — развивать и поддерживать такое ощутимо сложнее. Проверено.

Все компоненты организованы по доменному принципу в одной папке src/componens. Например, можно определить домены: Post — отображение публикации, PostForm — форма редактирования публикации.


Как создать доменный компонент — src/components/Post/Post.js.


Почему нельзя использовать index.js вместо Post.js — соблюдается уникальность имен файлов компонентов внутри проекта, так упрощается навигация по вкладкам редактора (и в WebStorm будет работать ценная функция "Find Usages" для контекстного меню выделенного файла — см. примечание).


Все компоненты в папке доменного компонента получают префикс доменного компонента (Post*.js).


Подпапки в папке доменного компонента не допускаются, внутри плоская структура файлов из компонентов-потомков (PostTitle.js, PostBody.js) и компонентов-предков (PostViewPage.js, PostListPage.js). Компоненты-потомки используются внутри доменного компонента, а компоненты-предки используются снаружи (в роутере, например).


Для импорта доменных компонентов следует задать внутри каждой папки доменного компонента свой package.json, в котором прописать точку входа "main":


{
  "name": "Post",
  "version": "0.0.0",
  "private": true,
  "main": "./Post.js",
}

Кроме того, внутри файла доменного компонента (Post.js) объявлен реэкспорт компонентов-предков:


import PostViewPage from './PostViewPage'
import PostListPage from './PostListPage'
//...
export { PostViewPage, PostListPage }
export default Post

К сожалению, нельзя использовать конструкцию "export from" (ограничение WebStorm), например:


export { default as PostViewPage } from './PostViewPage'

В результате не требуется явного доступа к файлам внутри папки компонентов, например:


import Post from 'components/Post/Post'

По соглашению, разрешается использовать импорт только по имени доменного компонента:


import Post, { PostViewPage, PostListPage } from 'components/Post'

Исходники


Примечание по функции "Find Usages" в WebStorm. Как минимум, есть три контекста использования: 1) по выделенному файлу, 2) по выделенной переменной или символу, 3) по выделенному default в экспорте компонента.


1) Выделим файл components/Post/PostViewPage.js, результат поиска:


// Post.js
import PostViewPage from './PostViewPage'

2) Выделим символ PostViewPage внутри файла PostViewPage.js, результат поиска:


// PostViewPage.js
PostViewPage.propTypes = {}

3) Выделим default в экспорте компонента PostViewPage, результат поиска:


// routes.js
import { PostViewPage } from 'components/Post'
<Route exact path="/post/:id(\d+)/" component={PostViewPage} />

Как видно, третий способ использования выдает наиболее полезную информацию для компонента-предка.


PS


CSS внутри компонентов

Найден правильный способ прикрутить Styled-JSX для Create React App. Теперь CSS-блоки живут внутри файлов компонентов естественным для себя образом — в CSS-формате (против инлайн-стилей JS-объектов). И не нужно беспокоиться за глобальную область видимости.


Абсолютные пути в импорте

Работают относительно папки src, пример:


import MyComponent from 'components/MyComponent'

Конфигурация babel-plugin-module-resolver

['module-resolver', { 'root': ['src'] }]

Настройка WebStorm

Для папки src в контекстом меню выполнить: Mark Directory as > Resource Root.


Настройка Atom

  • Установить плагин js-hyperclick.
  • Для доменных компонентов прописывать в package.json путь до src:
    "moduleRoots": ["../.."]
Поделиться с друзьями
-->

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


  1. copal
    09.04.2017 23:10

    В java и c# классы принято называть как, если Page, то MainPage или SomePage, если Model, то UserModel или PostModel. Не понятно чем руководствовался автор, надеюсь что не css стилем.

    Так же не совсем понятна мотивация складывать компоненты в папку components. Ведь все созданное на react по своему определению является компонентами. А желание привести код к повторному использованию должно подтолкнуть на объединение представления-реакт-компонента с логикой этого компонента. Только при таком раскладе можно перенести компонент без боли.

    Так же личный опыт подсказывает, что все проекты уникальны и по сути из проекта в проект мигрируют только ui, которые и следует выносить в отдельный модуль или в случаи со сборщиками в отдельный бандл. А вот компоненты MainPage или PostPage, хотя я называю их MainRoute и PostRoute будут состоять из тех самый ui, а так же будут являться уникальными для конкретного проекта и даже не стоит забивать себе голову чтобы сделать их переиспользуемыми.


  1. Luchnik22
    09.04.2017 23:38
    +3

    Я лично предпочитаю использовать index файлы, и у меня Atom он с этим отлично справляется. Думаю WebStorm тоже можно настроить на нормальное отображение файлов во вкладках.


    К тому же у меня в проекте импорты вида:


    import MyComponent from 'components/MyComponent';
    import { getDistributions } from 'actions';

    Достигается это за счёт настройки webpack конфига:


    resolve: {
        extensions: ['', '.jsx', '.js', '.css', '.json'],
        modules: [
          path.resolve('./src'),
          path.resolve('./node_modules'),
        ],
      },

    Если беспокоит линтер, то его тоже можно настроить:


    "settings": {
        "import/resolver": "webpack"
    }

    Более подробно eslint-import-resolver-webpack
    Если интересно более подробно, то могу написать пост.


    1. comerc
      09.04.2017 23:49
      -1

      Я лично предпочитаю использовать index файлы

      Экзорцизм в публикации про это, собственно. :)


      Если интересно более подробно, то могу написать пост.

      Конечно интересно!


      1. Luchnik22
        10.04.2017 00:02
        +2

        Хорошо, на следующих выходных напишу :) Просто, как мне кажется, создавать package.json файлики в каждом компоненте для исправления поиска и нормального отображения вкладок в IDE, немного изыбтычно, и нужно настраивать саму IDE.


        У меня Атом отображает два одинаковых файла так:



        1. vintage
          10.04.2017 00:09
          +2

          WebStorm тоже так умеет, где-то в настройках включается.


          1. comerc
            10.04.2017 11:04

            Оно из коробки работает:


            Perfect World:


            1. vintage
              10.04.2017 11:17

              Идеально было бы так:


              post/view/.js
              post/view/.test.js
              post/view/.css
              post/view/.tpl
              post/edit/.js
              post/edit/.test.js
              post/edit/.css
              post/edit/.tpl


              1. comerc
                10.04.2017 11:52
                +2

                > Подпапки в папке доменного компонента не допускаются, внутри плоская структура файлов

                Проходили. Как следствие размножения подпапок, плодятся компоненты с одинаковыми именами. Можно повеситься, перебирая List.js, Button.js etc. :)


                1. vintage
                  10.04.2017 13:03

                  Да нет, нормально получается. Если что, WebStorm умеет и по частям путей искать.


        1. comerc
          10.04.2017 00:12
          -1

          и нужно настраивать саму IDE

          IDE подкручивал для навигации по абсолютным путям — в любом случае нужно.


  1. gearbox
    10.04.2017 12:24
    +1

    Как подстроиться под webStorm. Пользователи Atom, Brackets и VS Code возмущены. Пользователи vim-а снисходительно улыбаются.

    Имхо — строить проект под редактор/IDE — мягко говоря глупость неосмотрительно.


    1. vintage
      10.04.2017 13:04
      +1

      Лучше если хоть в одной IDE будет удобно, чем когда неудобно в любой.


      1. gearbox
        10.04.2017 15:29

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