tribou / react-template

Build a server-rendered React app and share code across web, React Native, and Electron
Apache License 2.0
4 stars 9 forks source link

Directory Restructuring #49

Open tribou opened 6 years ago

tribou commented 6 years ago

Now that we have some large projects under our belt, it appears we're testing better ways to organize the folders. Let's discuss the options and perhaps get some example PRs to review.

src/components

Proposed new structure:

src/components/
├── App.android.js
├── App.ios.js
├── App.js
├── App.style.css
├── README.md
├── enhancers
│   └── withHandlers
│       └── index.js
├── index.js
├── layouts
│   └── SidebarLayout
│       ├── SidebarLayout.android.js
│       ├── SidebarLayout.ios.js
│       ├── SidebarLayout.js
│       ├── SidebarLayout.style.css
│       ├── SidebarLayout.style.js
│       ├── SidebarLayout.style.js
│       ├── SidebarLayout_test.js
│       └── index.js
├── routes
│   ├── NotFound
│   │   ├── NotFound.android.js
│   │   ├── NotFound.ios.js
│   │   ├── NotFound.js
│   │   ├── NotFound.style.css
│   │   ├── NotFound.style.js
│   │   ├── NotFound_test.js
│   │   └── index.js
│   └── Todos
│       ├── Todos.android.js
│       ├── Todos.ios.js
│       ├── Todos.js
│       ├── Todos.style.css
│       ├── Todos.style.js
│       ├── Todos_test.js
│       └── index.js
└── shared
    └── TextField
        ├── TextField.js
        ├── TextField.style.css
        ├── TextField_test.js
        ├── __snapshots__
        │   └── TextField_test.js.snap
        └── index.js

src/redux/modules

Possibly renamed to src/modules??

Many items can be proposed here... Moving API helper files here, etc. The idea would be to focus on Domain Driven Design and organize by domain (auth, users, entity, etc)

cc @davidcurras @doskogerman @zacacollier

tribou commented 6 years ago

Redux structure proposal in #59:

├── modules
│   ├── auth
│   │   ├── _test.js
│   │   ├── actions.js
│   │   ├── api.js
│   │   ├── consts.js
│   │   ├── initialState.js
│   │   ├── mocks.js
│   │   ├── reducer.js
│   │   └── types.js
zacacollier commented 6 years ago

@doskogerman recently refactored our project's structure somewhat according to the structure @tribou quoted in his initial comment

src
├── components
│   ├── App.index.js
│   ├── App.js
│   ├── App.style.css
│   ├── README.md
│   ├── layouts
│   │   ├── Landing
│   │   │   ├── Landing.index.js
│   │   │   ├── Landing.js
│   │   │   └── Landing.style.css
│   │   └── Main
│   │       ├── Main.index.js
│   │       ├── Main.js
│   │       └── Main.style.css
│   ├── routes
│   │   ├── Login
│   │   │   ├── Login.index.js
│   │   │   ├── Login.js
│   │   │   └── Login.style.css
├── redux
│   ├── modules
│   │   ├── auth
│   │   │   ├── _test.js
│   │   │   ├── index.js
│   │   │   └── types.js
├── helpers
│   ├── api
│   │   ├── auth
│   │   ├── index.js
│   │   ├── index_test.js
│   │   └── user
│   │       ├── index.js
│   │       ├── mocks.js
│   │       └── types.js

main differences being the layouts and routes component subdirectories (which, coincidentally enough, is a design pattern used in Gatsby.js)

and that the redux / API modules have type declarations co-located in a separate types.js file

I've found it's a very natural extension of the modular structure we're already used to, and once the layouts / routes directory restructuring is in place, it's easy to incrementally refactor an existing codebase

tribou commented 6 years ago

Excellent! I really like the idea of layouts and routes as well, so I'm glad that seems to be working well.

For the redux + API organization, I think there's a domain-driven organization that could help; but I'm hesitant on how detailed to break it up. For example, I like the idea of moving things into a domains/ directory inside src and apply a common pattern to each domain of an app rather than having the pieces scattered in separate "functional" directories or files (selectors, redux/modules, epics, etc). In addition, if we assume that we're always using redux-form, we could also separate things like validations.js for form validation.

The goal of a domain-driven structure would be to do the following:

1) Centralize the context for related pieces around the "domain" (e.g. why go to api/helpers + redux/modules + epics + selectors to find all of the related logic for every domain like auth, profile, todos, ...?) and 2) Enable future framework automation where domain and component/container boilerplate could be automatically generated from a CLI

Some ideas of automation:

tribou commented 6 years ago

Automation may be affected by this upcoming architectural change:

tribou commented 6 years ago

Also may be able to utilize facebook/jscodeshift to allow automatic updating of existing containers, modules, etc. with new properties and functions.

zacacollier commented 6 years ago

For the redux + API organization, I think there's a domain-driven organization that could help; but I'm hesitant on how detailed to break it up.

I see where you're coming from. For the sake of future automation via the fob CLI, the detailed approach we've taken might not be ideal.

Wanted to point out something I thought of - there is something to be said for having related logic split between higher-order domains such as /api, /redux, etc. To me, it's reminiscent of the way Linux / BSD filesystems are organized - specific root-level "domains" are split between /usr, /dev, /sys (deprecated, but good for the sake of illustration), etc. However, just because said approach is "the Unix way" doesn't mean it should be taken as gospel - in fact, Gobo Linux actually distinguishes itself by differing on this point.

A couple other (semi-)related ideas off the top of my head:

sls
├── serverless.yml
├── src
│   ├── users
│   │   ├── index.js
│   │   ├── _test.js
│   │   ├── types.js
│   │   ├── users.model.js
...     └── users.service.js
client
├── src
│   ├── users
│   │   ├── _test.js
│   │   ├── redux
│   │   │   ├── index.js
│   │   │   ├── _test.js
│   │   │   └── types.js
│   │   └── api
│   │   │   ├── index.js
│   │   │   ├── _test.js
│   │   │   └── types.js

even without the hypothetical options CLI flags, I'd be interested in adapting this opinionated approach to serverless projects 🤔

tribou commented 6 years ago

I just resurrected from the plague, so I didn't get to respond last week...

But that's VERY interesting! For auto-generation, I'm definitely in support of being able to swap Hapi.js with Serverless and apex/up as the server engine for the web component.

Feel free to share an example of how the sls files would be used specifically if you have any!