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-automationbut 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 componentA 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
SubComponentexports { 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
ReduxedComponentcomponent
- This is the presentational component for the
- ReduxedComponent.js
- This is the container component for the
ReduxedComponentcomponent
- This is the container component for the
- reducer.js
- This is the reducer for the
ReduxedComponentand all of its descendants
- This is the reducer for the
- index.js
- The aggregation and export of all files relevant to
ReduxedComponentexports { ReduxedComponent, ReduxedComponentActions, ReduxedComponentReducer }- Notice that
ReduxedComponentexported here is the presentational component
- The default export is the
ReduxedComponentcontainer (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