alan2207 / bulletproof-react

🛡️ ⚛️ A simple, scalable, and powerful architecture for building production ready React applications.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

bulletproof-react with file-based routing

sbhbenjamin opened this issue · comments

hello, I'm considering adopting Bulletproof-React's feature-based project structure in conjunction with Next.js. Given Next.js's file-based routing, some routes might reside outside of a feature – which I feel could potentially limit the ability to use shared components or utilities from within that feature. Has anyone faced similar challenges or have insights to share?

Hey @sbhbenjamin !

it is a good idea to define routes at the application level and then compose the pages with components from different features. I plan to update the demo app codebase to match that setup in the near future.

You can also check out the repository of my book where I covered building a Next.js application with a similar approach.(https://github.com/PacktPublishing/React-Application-Architecture-for-Production)

Basically, you can create as many components as you need in your features and then just compose them in pages.

Hey @alan2207, thanks for the prompt response!

For something like Next.js's new app router, I thought of having the following organisation based on your comments!

  • /app directory for the file-based routing
  • /features where the feature-based organisation lives
  • /shared which houses components, utilities and types that are shared across multiple features
/src
|-- /app                      # handles file-based navigation
|   |-- /home
|   |   |-- page.tsx
|   |-- /products
|   |   |-- /[id]
|   |   |   |-- page.tsx
|   |   |-- page.tsx
|   |-- /cart
|   |   |-- page.tsx
|   |-- /about
|   |   |-- page.tsx
|-- /features                 # houses feature-based code
|   |-- /auth
|   |   |-- /components
|   |   |   |-- LoginButton.tsx
|   |   |   |-- ProfileDropdown.tsx
|   |   |-- api.ts
|   |   |-- types.ts
|   |-- /product
|   |   |-- /components
|   |   |   |-- ProductList.tsx
|   |   |   |-- ProductDetails.tsx
|   |   |-- api.ts
|   |   |-- types.ts
|   |-- /cart
|   |   |-- /components
|   |   |   |-- CartList.tsx
|   |   |-- api.ts
|   |   |-- types.ts
|-- /shared                   # houses shared utilities
|   |-- /components
|   |   |-- Header.tsx
|   |   |-- Footer.tsx
|   |-- /utilities
|   |   |-- formatPrice.ts
|   |-- /types
|   |   |-- common.ts

Along these lines, Next.js offers features such as private folders and route groups, im not quite sure if that would be effective in achieving the strong cohesion in each feature. Do you think they can be helpful in achieving this?

Would love your thoughts on this, and will definitely check out your book – sounds like an amazing resource!

Hey @sbhbenjamin ,

In the new app router you could build your components within the private folders in the app folder, especially for components used once at that specific page and nowhere else. Colocation is a great thing for your codebase.

I would probably still consider having the features folder, which in that case could contain only domain-specific code(interfaces, types, utilities, etc.). Think of React/Next.js agnostic stuff
In your example, CartList would be in app/cart/components/cart-list.tsx but stuff like CartInterface or calculatePriceWithVAT function would go in /features/cart or wherever you want to organize it...

PS - the book is based on the old pages router but the concepts are pretty similar except now you are able to colocate more files close to your page files...

@alan2207 I see, so my understanding is that this results in 3 layers of locality:

  1. Shared layer: where we share code across features
  2. Feature layer: where we share code within a feature, among different pages
  3. Colocated layer: where we keep components and immediate dependencies together with the page that needs them

I'm curious, with paths like app/cart/components and features/cart/components, could this lead to moments of hesitation for developers about where to look for and place code? Considering that we are doubling up potential locations for similar code!

You can just start putting everything by default in /app/cart and if you need it somewhere else, you can move it out into features. For example, CartList belongs to /app/cart page but what if you need to render the same list when you click on the cart icon in the header? That's when you want to move it outside.

Hey @alan2207, that clarifies alot, thank you so much for your insights! :-)