What are some of the most common tasks when building and maintaining a project?
- Adding features
- Creating components, containers, and redux related data (if need be)
- Modifying existing features
- Finding components, containers and adding or removing things until the desired outcome is fulfilled
- Modifying existing features
- Adding features
- Updating
- This is pretty much only done to make it so that adding and modifying large amounts of things at once can be done faster and more efficiently than to work in the outdated codebase
Well, we should not really consider the initial buildout of a project as our main optimization metric as it only ever happens once in a project's lifecycle. Definitely, maintenance should be optimized for.
- They are unfamiliar with the code base
- Even if they wrote the codebase we will assume that they only know some general architecture as they have lost context working in other projects
- They want to locate where to add the feature and add it
- Finding things should be easy:
- Things that often change together should be close together (colocation)
- It should be obvious from the import statement what type a file is
- Adding things should be easy:
- Avoid too much nesting (Files should be easy to move around the project and relative importable (the webpack resolvers was a remedy to a problem that shouldn't exist)
With file structure there are a few ways to go about it:
- By Type of file
- Currently, we are using the type of file wherein we have our reducers, actions, components, containers all separated from each other. When adding a feature it is pretty hard to know where to start first (The component, wait but I don't have the data, what does the data looks like, do I need to fetch it and so on).
- By Feature
- I think a better way to do it would be to separate components by a feature like we did inside of the components folder of
web-automation
but with other related features close by like: containers and presentational component ( if needed: reducers, actions).
- I think a better way to do it would be to separate components by a feature like we did inside of the components folder of
A component named List
:
import List from './components/List';
If a component needs a container it should be default export because if a component needs a container it is extremely rare that you would use the component without the container. Instead, it should just be a named export like:
import List from './components/List'; // The container component
import { ListComponent } from './components/List'; // The presentational component
A sub-component named ListItem
:
import ListItem from './components/List/Item';
A page named View
:
import View from './views/View';
// or maybe
import View from './pages/View';
// or maybe
import View from './routes/View';
// vs. current
import View from './app/View';
A reducer specific to List
:
import ListReducer from './components/List/reducer';
// or
import { ListReducer } from './components/List';
// vs. current
import ListReducer from './reducers/List';
An action creator specific to List
:
import ListActions from './components/List/actions';
// or
import { ListActions } from './components/List';
// vs. current
import ListActions from './actions/List';
- components/
- ReduxedComponent/
- SubComponent/
- actions.js
- Action creators specific to
SubComponent
- Action creators specific to
- SubComponent.jsx
- The presentational component for
SubComponent
- The presentational component for
- index.js
- The aggregation and export of all files relevant to
SubComponent
exports { SubComponentActions };
- The default export would be the presentational component (
SubComponent.jsx
) in this case because this component does not depend on the redux stateexport default SubComponent;
- The aggregation and export of all files relevant to
- actions.js
- actions.js
- Action creators specific to ReduxedComponent and pulls from
SubComponent
's actions as well
- Action creators specific to ReduxedComponent and pulls from
- ReduxedComponent.jsx
- This is the presentational component for the
ReduxedComponent
component
- This is the presentational component for the
- ReduxedComponent.js
- This is the container component for the
ReduxedComponent
component
- This is the container component for the
- reducer.js
- This is the reducer for the
ReduxedComponent
and all of its descendants
- This is the reducer for the
- index.js
- The aggregation and export of all files relevant to
ReduxedComponent
exports { ReduxedComponent, ReduxedComponentActions, ReduxedComponentReducer }
- Notice that
ReduxedComponent
exported here is the presentational component
- The default export is the
ReduxedComponent
container (ReduxedComponent.js
)export default ReduxedComponent;
- The aggregation and export of all files relevant to
- SubComponent/
- ReduxedComponent/
In general, if you are looking for anything to do with ReduxedComponent
it's very clear what file you should be looking in based upon the file name and path. Except for looking at ReduxedComponent.js
from ReduxedComponent.jsx
the intuition should be that a .js
the file name should be a container while .jsx
should be presentational.
Keeps all related files grouped together in the same directory.
Allows for flexibility, more files can be added into this folder like: constants.js, actionTypes.js, utils/ subscribers/
basically anything that is related to the top level component should be placed inside of it.
Can create a deeply nested hierarchy if we do too many sub-groupings which makes digging for a file difficult
Leads to many files of the same names that are different only in the placement of the directory e.x. actions.js in ReduxedComponent/
and in OtherReduxedComponent/
- ReduxedComponent/
- ReduxedComponent.component.js
- Is the container component for
ReduxedComponent
- Is the container component for
- ReduxedComponent.jsx
- Is the presentational component for
ReduxedComponent
- Is the presentational component for
- ReduxedComponent.component.js