はじめに
以下の環境で構築していきます
- Next.js 13
- TypeScript
- Eslint
- Prettier
- Recoil
環境構築 (Eslint,Prettier)
yarn create next-app --typescript
cd frontend
# prettierをインストール
yarn add -D prettier eslint-config-prettier
以下ファイルを変更&追加
ディレクトリ構造
├── node_modules
├── public
├── src
├── .eslintrc
├── .gitignore
├── .prettierignore
├── .prettierrc.json
├── next-env.d.ts
├── next.config.js
├── package.json
├── README.md
├── tsconfig.json
└── yarn.lock
.eslintrc.json
{
"env": {
"browser": true,
"node": true,
"es2022": true
},
"parser": "@typescript-eslint/parser",
"parserOptions": {
"ecmaVersion": "latest",
"project": "./tsconfig.json",
"ecmaFeatures": {
"jsx": true
}
},
"extends": [
"eslint:recommended",
"next/core-web-vitals",
"plugin:@typescript-eslint/recommended",
"plugin:react/recommended",
"airbnb",
"airbnb-typescript",
"prettier"
],
"plugins": [
"@typescript-eslint",
"react"
],
"rules": {
"react/react-in-jsx-scope": "off",
"react/function-component-definition": [
2,
{
"namedComponents": "arrow-function",
"unnamedComponents": "arrow-function"
}
],
"react/prop-types": "off"
}
}
.prettierrc.json
{
"endOfLine": "lf",
"semi": true,
"singleQuote": true,
"jsxSingleQuote": false,
"tabWidth": 2,
"trailingComma": "es5",
"printWidth": 60
}
.prettierignore
# next.js build output
.next
out
# dotenv environment variables file (build for Zeit Now)
.env
.env.local
# Dependency directories
node_modules
# Logs
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# text
*.md
*.txt
*.csv
VSCodeのPrettierの拡張機能を追加
※プロジェクトによってはコードの整形が勝手に行われると嫌な時があるので適宜無効にしたりVSCodeの設定ファイルを書き換えることを推奨
環境構築 (Recoil)
※正しいアーキテクチャではない可能性があるので参考までに使用してください。他の方のアーキテクチャも参考にしてみてください。
yarn add recoil
ディレクトリ構造
src
├── components
└── TestChild.tsx
├── pages
├── _app.tsx
├── _document.tsx
└── index.tsx
├── store
├── selectors
└── カスタムフックに使用
└── atoms
└── index.ts
├── styles
└── yarn.lock
_app.tsx
import '@/styles/globals.css';
import type { AppProps } from 'next/app';
import { RecoilRoot } from 'recoil';
export default function App({
Component,
pageProps,
}: AppProps) {
return (
<RecoilRoot>
<Component {...pageProps} />
</RecoilRoot>
);
}
index.tsx
import TestChild from '@/components/TestChild';
import { textState } from '@/store/atoms/index';
import styles from '@/styles/Home.module.css';
import { useRecoilState } from 'recoil';
export default function Home() {
const [text, setText] = useRecoilState(textState);
return (
<>
<main>
<p>{text}</p>
<TestChild />
</main>
</>
);
}
atoms/index.ts
import { atom } from 'recoil';
export const textState = atom<string>({
key: 'textState', // unique ID (with respect to other atoms/selectors)
default: 'Hello World!', // default value (aka initial value)
});
TestChild.tsx
import { textState } from '@/store/atoms/index';
import { useRecoilState } from 'recoil';
const TestChild = () => {
const [text, setText] = useRecoilState(textState);
return (
<button onClick={() => setText('にゃっはろー')}>
click
</button>
);
};
export default TestChild;
環境構築 (Emotion)
# emotionをインストール
yarn add @emotion/react
tsconfig.json
{
"compilerOptions": {
"target": "es5",
"lib": ["dom", "dom.iterable", "esnext"],
"allowJs": true,
"skipLibCheck": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"noEmit": true,
"esModuleInterop": true,
"module": "esnext",
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"jsx": "preserve",
+ "jsxImportSource": "@emotion/react",
"incremental": true,
"paths": {
"@/*": ["./src/*"]
}
},
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"],
"exclude": ["node_modules"]
}