Project Structure - 509dave16/react-native-prototypes GitHub Wiki

Project Structure Methods

  • FTF(File Type First)(aka Directory Per Concept) - for the types(or concepts) of files that make sense in your application you make a folder for each(aka reducers folder)
    • Pros: Great a for a small application that is considered one feature. Such as a package like body-parser
    • Cons: Does not hold up in an application where there are many features. You wouldn't want to mix the components, actions, reducers, and styles of different features all together. HOW ConFUsinG!!!
  • Pods(aka Feature First) - this is like the evolution of FTF by having file type folders for each feature. So the authentication feature would have the components, actions, reducers, and styles folders just like the profile feature would. Yaay for consistency! Hurrah!! We aren't confused about what's what anymore!!!
    • Pros: Look at note 1 here
    • Cons: Look at note 1 here
  • File Per Concept - Even smaller than a FTF. This not for a feature. You are literally testing some minute operation very quickly in this case. Or attempting to demonstrate a very small concept. To compare to FTF you would literally have actions.js, component.js, styles.js, and reducer.js.
    • Pros: Look at note 2 here
  • Directory Per Component - this is a slight alteration to FTF. Essentially for the file type component you have separate directories for each component file. This is so that you can group the styles and specs for a component in one place. You could have actions, routes, reducers, and other file types in the component folder if it makes sense.
    • Pros: Look at note 2 here
  • Directory Per View - this is similar to Directory Per Component. We now have a Routes directory in our components directory. And there is now a views directory at the top level. I think a view is suppose to be considered like pages in your app that you navigate between. NOTE: might be a nice distinction in terms of knowing where all the pages(views) exist vs the widgets/pieces(components).
    • Pros: Look at note 2 here
  • Nesting Per Concept - this is like a more generic form of Pods. Pods is about Features, whereas NPC is more about rules for nesting entities of a concept and accessing them.
    • Pros: Look at note 3 here

Chosen Structure

Nesting Per Concept

Reasoning

This project structure appeared to be the most scalable and readable. Directory per Concept was certainly going to get hairy very quickly as we added more features. And Directory per Feature would have been fine, but without any concepts you have no idea the scale of a feature. Is it a widget? Is it a page? Is it a workflow? You have no idea. I may change some of the conventions related to using Nesting Per Concept but for now this how it's going to work:

/src
  /components -- common can be used by any scene
    /Button -- Example!!! This is by no means actual composition
      /images
      /locales
      /__tests__
      /index.js -- we will always have this file to expose the actual component
      /styles.js
    ...
  /scenes - can have their own isolated services
    /Home
      /components - can be used by any concrete sub-component of the scene
        /ButtonLike - can use Button since it's a global component
      /services
        /processData
      /index.js
      /styles.js
    ...
  /services
    /geolocation
    /storage
      /memory
        /redux
      /local
        /async-storage
      /remote
        /firebase

Above is the gist of what our structure will look like. Makes sense to me! components, scenes, and services. I'd like to make components and scenes fall under another folder like views. But it's kind of unnecessary.

NPC Rules to follow

  • A component can define nested components or services. It cannot use or define scenes.
  • A scene can define nested components, scenes, or services.
  • A service can define nested services. It cannot use or define components or scenes.
  • Each storage entity is standalone. No nesting.
  • Nested entities can only use other entities that are defined by a parent entity.

Component Rules to follow

  • Driver is a term used to describe a component that is connected to the redux store
  • Display is a term used to describe a component that is pure presentation(for the most part). Though there are some situations like inputs that capture user data where we would want to use local state that is completely isolated.
  • Always use an index.js to expose the components, it's constants, any action creators, and any selectors
  • When to define Driver and Display pairs components directly in an index.js file?
    • When you don't want to change the behavior by dynamically selecting a Driver component
    • When you have a concrete component pair that are not going to be re-used

Data/Service folder notes regarding reducers

Where do we want reducers to be placed? We would only want them to ever be tied to a particular scene or component? Maybe? No. If the state data access is isolated to a scene or a component and is not being accessed super deep in the tree, then we shouldn't even need reducers. Local state should be enough. In the case of the state not being isolated like in the case of most resources/models, we should put reducers in either the data or services folders. Not sure which makes more sense. I think of data as storage somewhere. Reducers are in a way data(structures) though too, but in memory. Do we want to have a distinction? I would hope so. The problem is that reducers also have selectors and actions that do things. Which models have to have as well? Data to me is more like just straight json files like config files. I think it's okay to differentiate by memory, local, and remote storage. We can always think later of a way to abstract the app's interactions with those different forms of storage. I think the only ones though that really need to be abstracted are remote and local. In any case let's do it!!!

Notes regarding services and storage

It's hard to draw a line between the two: services and storage. A service that is not interacting with something remote or directly related to storage of some kind is very rare. I can think of things like camera, gyroscope, etc... . However in reality, I think storage is a subset of services. Just like on Windows, where there are all these services that exist for apps to use or that autonomously do things. I'm sure there are services for storage running on Windows :) !

notes

  1. Refer to this article for exposition on FTF and Pods.
  2. Refer to this article for exposition on File Per Concept, Directory Per Concept, Directory Per Component, and Directory Per View
  3. Refer to this article for exposition on the Nesting Per Concept