React App File Structure. – DEV Community



Intro

The issue of organizing information inside an utility is beginning when multiple particular person works on the mission and the dimensions of the code base growss to such stage, that it is tough to maintain all the pieces in thoughts. That is why we’re at all times making an attempt to make file construction extra apparent, so it may be used comfortably and rapidly.

React would not dictate it is utility structure, leaving full freedom in how the appliance information are organized: https://reactjs.org/docs/faq-structure.html

I’ve spent fairly a time to search out strategy for my mission, however first, we want some context:

  1. Fundamental language – TypeScript
  2. UI library – React
  3. State supervisor – MobX
  4. Authoring instrument for CSS – JSS Kinds
  5. Testing library – JEST

Let’s speak in regards to the particulars. No person is aware of why, but it surely was determined to rewrite the 5 years outdated mission from ES+Redux to TS+MobX, which already had the minimal set of options to have the ability to promote it and change into worthwhile. In fact, if I used to be there from the beginning I would like TS+MobX to ES+Redux, however I’d by no means comply with rewrite my present mission from one stack to a different. Be happy to jot down within the feedback if you wish to hear this story.

Additionally, within the means of discovering a file construction that may match to mission, I’ve learn some articles:
1) https://www.taniarascia.com/react-architecture-directory-structure/
1) https://www.robinwieruch.de/react-folder-structure/



Current options

Our mission was initially structured for a world state, however on the similar time it had a pseudo-modular construction with redundant nesting. Why do I think about our earlier construction pseudo-modular? The extent of dependencies between the modules was very excessive and didn’t permit us to maneuver one of many modules right into a separate repository with out an a number of code duplication, which meant that this didn’t give us something however a extra complicated construction and intensive nesting. Roughly it appeared like this:

.
├── /modules
│   └── /ModuleName1
│        └── /src
│            └── /js
│                ├── /api
│                ├── /actions
│                ├── /elements
│                ├── /containers
│                ├── /reducers
│                └── /shops
└── /src
    ├── /api
    ├── /belongings
    ├── /elements
    ├── /constants
    ├── /containers
    ├── /icons
    ├── /reducers
    ├── /shops
    ├── /types
    ├── /utils
    ├── index.js
    └── App.js
Enter fullscreen mode

Exit fullscreen mode

It’s secure to imagine that this answer is predicated on the acceptance of the frontend developer group, which is predicated on the practical naming of the code inside. Right here is an instance:

.
└── /src
    ├── /actions
    ├── /belongings
    ├── /elements
    ├── /constants
    ├── /containers
    ├── /icons
    ├── /reducers
    ├── /shops
    ├── /types
    ├── /utils
    ├── index.js
    └── App.js
Enter fullscreen mode

Exit fullscreen mode

Each approaches have the correct to exist, and to be truthful, the second variant with assist of aliases for WebPack and properly organized index.ts, will shut the issue of redundant nesting. Nonetheless, it requires extra steps to take care of the code.

So, what has modified with the transferring away from the Redux world retailer (and all associated libraries Thunk, reselect, Recompose, and so on.)? It grew to become potential to jot down atomic storages, i.e. when the storages are written particularly for the part and may be related at any stage within the supplier. In fact, this strategy requires a special strategy to jot down the part. There is no such thing as a pressing must hyperlink Reducers in Mix, and gather them all through the mission. Or perhaps you needn’t gather them at throughout elements and put them in the identical listing? I do not assume it should significantly simplifies the notion, as a result of you need to begin to write the complicated imports (aliases) within the second case, and the listing Reducers threatens to develop to 15-20 information at one stage, which can make worse search and visible notion.

Throughout my seek for the optimum answer, I’ve discovered an alternative choice, proposed by Robin Wieruch (hyperlink initially of the article):

- src/
--- App/
----- index.js
----- part.js
----- check.js
----- fashion.css
--- Listing/
----- index.js
----- part.js
----- check.js
----- fashion.css
----- ListItem/
------- index.js
------- part.js
------- check.js
------- fashion.css
Enter fullscreen mode

Exit fullscreen mode

There are some attention-grabbing ideas on this article, that resonates with my ideas in regards to the construction of the file construction in React. However it has it is personal flaws, which are apparent to me. The primary one which catches my eye – fast entry to information primarily based on identify which is just lacking, as hottest code editors and IDEs means that you can rapidly discover a file simply by first letters within the identify, with this strategy you possibly can’t try this. Kind part.js within the seek for this structure and you will see what I imply.



What we got here up with

In consequence, after analyzing the prevailing options and our expertise, we developed our strategy to organizing the information inside the mission:

  1. In any case, all of the code is in src. And src is the basis listing for all of the code. It’s potential to repair this with an alias in webpack.
  .
  └── /src
Enter fullscreen mode

Exit fullscreen mode

There is no such thing as a motive to place any pages or elements into modules. Any code that must be put right into a separate utility module must be mentioned individually with the assistance of a particular choice framework, the place the explanations, penalties and course of can be described individually.

  1. On the root of the repository, the primary division is by the identify of the part or web page.
  .
  └── /src
      ├── /App
      │   └── App.ts
      ├── /Header
      │   └── Header.ts
      ├── /Portal
      │   └── Portal.ts
      └── /Creation
          └── Creation.ts
Enter fullscreen mode

Exit fullscreen mode

  1. We abandon elements, containers, shops, api, types exterior the context of a part. And within the file construction, there are now not pointless nesting, however folders show the aim and content material of the folder.
  .
  └── /src
      ├── /App
      ├── /Header
      ├── /Portal
      │   ├── Portal.api.ts
      │   ├── Portal.retailer.ts
      │   ├── Portal.interface.ts
      │   ├── Portal.types.ts
      │   └── Portal.ts
      └── /Creation
Enter fullscreen mode

Exit fullscreen mode

  1. We determined to maintain solely belongings and checks folders to differentiate information indirectly associated to growth, however they need to be positioned as shut as potential to the place of direct use. If desired, an underscore image could also be used initially and/or finish of the identify to make sure that such directories are positioned initially of the file checklist.
  .
  └── /src
      ├── /App
      ├── /Header
      ├── /Portal
      │   ├── /__tests__
      │   ├── /_assets
      │   ├── Portal.api.ts
      │   ├── Portal.retailer.ts
      │   ├── Portal.interface.ts
      │   ├── Portal.types.ts
      │   └── Portal.ts
      └── /Creation
Enter fullscreen mode

Exit fullscreen mode

  1. Whether it is obligatory to cut back the size of the file to enhance the readability of the code, elements of the logic may be put in separate information (restricted by the allowable size of the file is finest set on the linter stage). Such elements must be positioned with cheap nesting. Just one stage of nesting is allowed for every part. There is no such thing as a sense to go one or two ranges inside.
  .
  └── /src
      ├── /App
      ├── /Header
      ├── /Portal
      │   ├── /_tests
      │   ├── /_assets
      │   ├── /PortalSearchBar
      │   │   ├── PortalSearchBar.types.ts
      │   │   └── PortalSearchBar.ts
      │   ├── Portal.api.ts
      │   ├── Portal.retailer.ts
      │   ├── Portal.interface.ts
      │   ├── Portal.types.ts
      │   └── Portal.ts
      └── /Creation
Enter fullscreen mode

Exit fullscreen mode



Conclusions.

In my view, the proposed construction:

  1. helps the developer to bear in mind MVV/MVC paradigm
  2. Plan part design upfront
  3. Spend much less time looking for the elements, inside file tree and fast entry panel as properly

Is it 100% optimum and appropriate mannequin for everybody? Undoubtedly not, however in our mission, it clearly is.
So in case you have ideas or feedback on this, please write to me @jchouse

Thanks for:

Add a Comment

Your email address will not be published. Required fields are marked *