Next.js template
鳥山明
Posted on November 8, 2022
https://github.com/akira-toriyama/next.js-tpl
Next.js template
App
Displays the data registered in Hygraph.
Design system
This is a design system, but it does not use styles.
React has various ways to apply styles, such as css in js, css module, comport library, etc., and there is no best practice. Please consider the style in consideration of the contents of your application.
How to use
Required libraries
First.
Prepare environment variables and schema for mock.
The SCHEMA_DOWNLOAD_URL
in .env.example
is the URL of the Hygraph resource. Please prepare it by yourself at the time of development. It is released to the public for operation check.
yarn mockServer
yarn generate:fromGQL
yarn dev
open "http://localhost:4000/graphql"
open "http://localhost:4000/voyager"
open "http://localhost:3000"
Development
During development, develop while communicating with the mock server.
yarn mockServer
yarn generate:fromGQL
yarn dev
open "http://localhost:4000/graphql"
open "http://localhost:4000/voyager"
open "http://localhost:3000"
design system
storybook
is well known, but we use ladle
.
yarn designSystem
open "http://localhost:6006"
comport generation
Generate comport with hygen
.
# Please git commit in advance.
yarn generate:ui/general
yarn generate:ui/domain
Snapshot update
Update snapshot when adding or updating stories.tsx
.
# It takes time.
yarn updateSnapshot
directory structure.
src
├── env.ts
├── infra
│ └── graphql
│ ├── client.ts
│ ├── types.ts
│ └── util
│ ├── index.ts
│ ├── util.test.ts
│ └── util.ts
└── ui
├── domain
│ └── item
│ ├── Item
│ │ ├── coLocation
│ │ │ ├── dao.ts
│ │ │ ├── Item.gql.generated.ts
│ │ │ └── Item.gql.ts
│ │ ├── component
│ │ │ ├── index.ts
│ │ │ ├── Item.stories.tsx
│ │ │ ├── Item.test.tsx
│ │ │ └── Item.tsx
│ │ ├── hook
│ │ │ ├── index.ts
│ │ │ ├── item.hook.test.ts
│ │ │ ├── item.hook.ts
│ │ │ └── service
│ │ │ ├── index.ts
│ │ │ ├── service.test.ts
│ │ │ └── service.ts
│ │ ├── index.ts
│ │ └── Item.type.ts
│ └── Items
│ ├── coLocation
│ │ ├── dao.ts
│ │ ├── Items.gql.generated.ts
│ │ └── Items.gql.ts
│ ├── component
│ │ ├── index.ts
│ │ ├── Items.stories.tsx
│ │ ├── Items.test.tsx
│ │ └── Items.tsx
│ ├── hook
│ │ ├── index.ts
│ │ ├── items.hook.test.ts
│ │ ├── items.hook.ts
│ │ └── service
│ │ ├── index.ts
│ │ ├── service.test.ts
│ │ └── service.ts
│ ├── index.ts
│ └── Items.type.ts
├── general
│ ├── Card
│ │ ├── Card.stories.tsx
│ │ ├── Card.test.tsx
│ │ ├── Card.tsx
│ │ └── index.ts
│ └── List
│ ├── index.ts
│ ├── List.stories.tsx
│ ├── List.test.tsx
│ └── List.tsx
├── provider
│ ├── ErrorBoundary.tsx
│ ├── ReactQuery.tsx
│ └── Wrapper.tsx
└── util
└── tag
├── index.ts
├── tag.test.ts
└── tag.ts
Development flow.
GithubActions is executed when you submit a pull request on main branch. (example)
GithubActions executes type checking, lint, unused code detection, snapshotting, etc. App and Design system are also published by pull requests.
Implementation policy
Directory structure
The directory structure directly under src/ is based on the layered architecture. Please be aware of where to implement this process.
Avoid using src/graphql, src/component, etc., as it will result in a technology-driven structure.
mock server
During development, it is not necessary to communicate with the actual resource. Prepare a mock that returns convenient data in _server/grphqlServer/mocks.ts.
Template.
Use yarn generate:ui/general
, yarn generate:ui/domain
to align the basic implementation.
domain component
In SPA, UI and logic and UI and storage are tightly coupled. Please do not prepare directories with the same name, but use extensions and directory structure to express the roles.
# Bad
src/graphql/animal/cat.gql.ts
src/component/animal/Cat.tsx
# Good
src/ui/domain/animal/cat/coLocation/cat.gql.ts
src/ui/domain/animal/cat/component/Cat.tsx
Not everything fits this rule, but implement everything of interest in src/ui/domain/.
tsx
Do not implement non-testable components.
Please refer to eslint-plugin-use-encapsulation.
# Bad
const Cat: React.FC = () => {
const [v, setV] = useState("Tama");
return <>name of the cat {v}</>;
};
# Good
const useCat = () => {
const [v, setV] = useState("Tama");
return {
name: v,
};
};
const Cat: React.FC = () => {
const cat = useCat();
return <>cat's name {cat.name}</>;
};
Testing
Please write unit tests well. Don't write tests knowing too much about the processing of the file you are importing
.
state.
ts-pattern, type refinement, more state, etc. __tag
is better than isXxx
.
example
Posted on November 8, 2022
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.