Feature oriented Next.js
This proposes a truly feature-oriented structure to Next.js.
๐ช Looking for an module?
๐ Included
- TypeScript
- styled-components
- styled-normalize: normalize.css for styled-components
Structure
๐ฉโโค๏ธโ๐จ Tightly coupled, Feature-oriented
โ As-is
.
โโโ components/ 1๏ธโฃ
โ โโโ Home/
โ โ โโโ Button.tsx
โ โ โโโ Header.tsx
โ โ โโโ FirstSection.tsx
โ โ โโโ SecondSection.tsx
โ โโโ Profile/
โโโ utils/
โ โโโ Home/
โ โโโ Profile/
โโโ public/
โโโ pages/ 2๏ธโฃ
โโโ index.tsx # Home
โโโ profile.tsx # Profile
The most commonly used structure for Next.js is like the above; Each page component goes into the pages
folder, with the intended route as their filename. Uncommon code fragments used only by specific pages, like components and utilities, are grouped inside each folder named after the page component. So the pages and their components were bound to be loosely coupled.
Because pages are strongly dependent on components of the same interest, this makes it difficult to find the fragments used in the page - or identify related changes inside your domain.
โ To-be
.
โโโ public/
โโโ src/
โโโ domains/
โ โโโ Home/ 1๏ธโฃ
โ โ โโโ components/
โ โ โโโ utils/
โ โ โโโ hooks/
โ โ โโโ HomePage.tsx
โ โโโ Profile/
โโโ pages/ โญ๏ธ
โโโ index.tsx
โโโ profile.tsx
How's this? ๐
The pages are separated by each domain and tightly coupled to the components it consumes.
// index.tsx
import { HomePage } from 'src/domains/Home/HomePage'
const Home = () => <HomePage />
export default Home
In this structure, the files inside the original pages
folder have only one lightweight role: Importing 'real' page components from the domain folder and linking them to the desired path.
This way we can...
๐ Link multiple routes to one page
You can easily link multiple routes to one page. You can just import the page with another route and that's it.
// index.tsx
import { HomePage } from 'src/domains/Home/HomePage'
const Index = () => <HomePage />
export default Index
// home.tsx
import { HomePage } from 'src/domains/Home/HomePage'
const Home = () => <HomePage />
export default Home
Write tests next each page
TBD