This doc describres the new structure for the files and folders, besides It's conventions and best practices.
It was decided to use a modular architecture for a gradual refactoring of the app, considering each module being a feature/scope of the app.
Motivation:
- Separated structure (decoupling logic between features)
- Gradual refactoring
- Better maintainability
- Technologies agnostic
This means that the code should flow in one direction, from shared parts of the code to the application (shared -> modules-> app).
As you can see, the shared parts can be used by any part of the codebase, but the modules can only import from shared parts and the app can import from modules and shared parts.
...
βββ src/
βββ assets/
βββ components/
β βββ ui/
β ...
βββ consts/
βββ helpers/
βββ hooks/
βββ modules/
β βββ login/
β β βββ index.js (module public API)
β β βββ components/
β β βββ consts/
β β βββ hooks/
β β βββ screens/
β β βββ services/
β β βββ store/
β β βββ types/
β β ...
β βββ registration/
β βββ user-profile/
β βββ products/
| ...
βββ screens/
βββ services/
βββ store/
βββ types/
βββ utils/
NOTE: You don't need all of these folders for every feature. Only include the ones that are necessary for the feature.
- utils: Utilities for universal logic that is not related to business logic or any technologies, e.g. string manipulations, mathematic calculations, etc.
- helpers: Provides business-specific utilities.
Principles:
- Architectures should tell readers about the system, not the frameworks used (Bob Martin says in his article Screaming Architecture, Bob Martin)
- Instead of
MyComponent.js
π , writemy-component.js
β . - Instead of
useMyHook.js
π , writeuse-my-hook.js
β .
Motivation:
- Fewer git conflicts due to case-sensitivity issues
- Better alignment with modern web development practices
Every module should have a barrel file(index.ts
) used as a way to expose a public API for everything that is usable outside the module. This file should export only the code you want to be accessible outside the module.
Eslint rule to automate this:
{
"rules": {
"no-restricted-imports": ["error", { "patterns": ["@/modules/*/*"] }]
}
}
- π
Wrong:
import { Button } from "../../components/button"
; - β
Correct:
import { Button } from "@/components/button"
;
- Be aware of the business logic to make the right grouping decisions when creating new stuff/modules.
- Always try to transform
.js
files into.ts
- Always try to put right files in appropriate folders
- Always try to break big files into smaller ones
Question | If yes | If no |
---|---|---|
Is it shared functionality across modules? | Inside /src/{functionality} |
Inside appropriate module /src/modules/{module}/{functionality} |
Do I have time to transform this file into Typescript? | Change extension to .ts and make minimal typings | Create a // TODO: Change to typescript commentary |
Is this file too big? | Break into smaller ones | Do nothing |