The official emah website built in Next.js and Typescript with TailwindCSS for styling and R3F for 3D graphics.
- Node.js v18.12.1
- Next.js v13.0.7
- React.js v18.2.0
- Typescript v4.9.4
- TailwindCSS v3.2.4
- R3F v8.9.1
- StandardJS v17.0.0
Using NextJS ESLint with StandardJS, is necessary the following configuration for eslintrc file to ensure ESLint works propertly with React components:
"extends": [
"next/core-web-vitals",
"./node_modules/standard/eslintrc.json"
]
I'm using the src folder for keep code at a different level than configurations and miscellaneous files.
This is the structure I use for my Next.js projects:
We can express the above image with the following structure:
- src
- app
- core
- components (domain)
- pages
- api
Contains code that is being used by the special pages/_app.tsx
Next.js file, like:
- Components
- The store of the global state
- Business logic
- And more...
We could develop our folder structure in this way:
- src
- app
- layout
- store
- ...
This layer is used to place all unrelated to our domain
The core and the domain of a project, in my view, should be kept well separate.
Hard rule: the core layer can never import anything from the domain layer.
If something within the core layer needs something from the domain, it probably does not belong to the core layer.
For example:
- The database connector functions
- The utils for authentification
- The email provider
- And more...
The core layer provides the domain with the necessary tools for the application to work, for example, authenticating, querying the DB, or sending emails. But does not know how the consumer uses these tools.
We could develop our folder structure in this way:
- src
- core
- database
- connector.ts
- ...
- auth
- auth.ts
- ...
The business domain is the area of control or a sphere of knowledge, such as, the group of entities, relationships, and behaviors of the business model, implemented as code.
We can express the domain layer with the following structure:
- src
- components
The components that make up our app pages.
The business-logic side keep a lot of things, such as queries, or functions that mutate data, are all at the same folder that components and they can be reusable across components.
- Custom hooks
- Configurations
- Queries
- And all utilities related to the domain
We could develop our folder structure in this way:
- src
- components
- input
- CallToAction
- index.tsx
- hooks
- utils
- queries
- navigation
- Navbar
- index.tsx
- hooks
- config
- sections
- Hero.tsx
Next.js's router is file-system based, the folder pages is a Next-specific directory to place our API.
We could develop our folder structure in this way:
- src
- pages
- api
- Search
- [keyword].ts
- products
- [id].tsx
Something important to clarify is the rules I have around importing between layers.
Typically, an inner layer cannot import from an outer layer, that means that core cannot import from the domain layer, and the latter cannot import from pages.
Wrong
Ok
This rule can ensure your core is decoupled from the domain to avoid cyclical dependencies and keep your architecture untangled.
We can ensure that we're using the rules above correctly when importing files in our application.
EsLint can help us by adding the following configuration, can automatically warn you that you're importing from the wrong paths:
"rules": {
"import/no-restricted-paths": [
"error",
{
"zones": [
{
"target": "./src/core",
"from": "./src/components"
},
{
"target": "./src/core",
"from": "./src/pages"
},
{
"target": "./src/components",
"from": "./src/pages"
},
{
"target": "./src/core",
"from": "./src/app"
},
{
"target": "./src/components",
"from": "./src/app"
}
]
}
]
}
- Queries## Getting started
I recommend use pnpm because it hold all the packages at a global (centralized) store and use them if needed by other projects too by creating hard links to it.
- Clone the project
$ git clone https://github.com/saufth/emah.git/
- Install the dependencies:
$ pnpm install (recommended)
# or
$ yarn
# or
$ npm install
- Run the development server
pnpm dev (recommended)
# or
yarn dev
# or
npm run dev
Open http://localhost:3000/ with your browser to see the result.
Copyright © 2022 emah. All rights reserved.