Skip to content

Instantly share code, notes, and snippets.

@lucasalmeida92
Last active February 12, 2025 14:38
Show Gist options
  • Save lucasalmeida92/d5b2d4c5edc2ca81267e2c3b089c5c06 to your computer and use it in GitHub Desktop.
Save lucasalmeida92/d5b2d4c5edc2ca81267e2c3b089c5c06 to your computer and use it in GitHub Desktop.
MODULAR-ARCHITECTURE.md

πŸ†• New structure

This doc describres the new structure for the files and folders, besides It's conventions and best practices.

🧱 Modular architecture

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

Unidirectional codebase architecture.

This means that the code should flow in one direction, from shared parts of the code to the application (shared -> modules-> app).

image

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.

πŸ“ Base structure

...
└── 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 VS helpers:

  • 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)

✏️ Naming conventions

kebab-case for File and Folder Names

  • Instead of MyComponent.jsπŸ™…, write my-component.jsβœ….
  • Instead of useMyHook.jsπŸ™…, write use-my-hook.jsβœ….

Motivation:

  • Fewer git conflicts due to case-sensitivity issues
  • Better alignment with modern web development practices kent-c-dodds-kebab-case.png

πŸ”Œ Exposing Modules

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/*/*"] }]
  }
}

πŸ”Œ Importing stuff

Absolute Imports

  • πŸ™…Wrong: import { Button } from "../../components/button";
  • βœ…Correct: import { Button } from "@/components/button";

βž• Creating new stuff

  • 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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment