Next.jsプロジェクト構築備忘録

# はじめに
Next.jsプロジェクト構築の楽をしたいので、備忘録として残しておきます。

# プロジェクト作成
下記コマンドを実行し、プロジェクトの雛形を作成します。

```shell
docker run --rm -it -v $PWD:/app -w /app node:20-slim \
sh -c 'npm install -g npm && npx create-next-app@latest --ts'   
```


設定は以下とします。
```terminal
✔ What is your project named? … nextjs-sample（任意の名前)
✔ Would you like to use ESLint? … Yes
✔ Would you like to use Tailwind CSS? … Yes
✔ Would you like to use `src/` directory? … No
✔ Would you like to use App Router? (recommended) … Yes
✔ Would you like to customize the default import alias (@/*)? …　　Yes
✔ What import alias would you like configured? … @/*
```

# Docker関連ファイル作成
プロジェクト作成後にできたプロジェクトルートフォルダに以下の構成でファイルを配置します。
```
プロジェクトルート
├─ .devcontainer
|  └─ devcontainer.json
├─ docker-compose.yml
└─ Dockerfile
```

``` json:.devcontainer.json
{
    "service": "nextjs-sample",
    "dockerComposeFile": "../docker-compose.yml",
    "portsAttributes": {
    "onAutoForward": {
        "label": "Application",
        "onAutoForward": "ignore"
      }
    },
    "workspaceFolder": "/workdir",
    "customizations": {
      "vscode": {
        "extensions": ["eamodio.gitlens", "dbaeumer.vscode-eslint", "esbenp.prettier-vscode"],
        "settings": {
          "prettier.configPath": ".prettierrc.json",
          "editor.defaultFormatter": "esbenp.prettier-vscode",
          "editor.formatOnSave": true,
          "editor.codeActionsOnSave": {
            "source.fixAll.eslint": true
          },
          "editor.tabSize": 2
        }
      }
    }
}
```
```yml:docker-compose.yml
version: '3.9'
services:
  nextjs-sample:
    ports:
      - 3000:3000
    build:
      context: .
      dockerfile: Dockerfile
    volumes:
      - .:/workdir
    tty: true
```

```Dockerfile:Dockerfile
FROM node:20-slim

RUN apt-get update && \
    apt-get install -y git vim locales-all && \
    npm update -g npm

ENV LANG ja_JP.UTF-8
ENV LANGUAGE ja_JP:ja
ENV LC_ALL ja_JP.UTF-8

WORKDIR /workdir
```

# ESLint設定
ここからはdevcontainerを使用したコンテナ内で行います。

```shell
npm install --save-dev @typescript-eslint/eslint-plugin
```

下記ファイルを以下のように変更します。
ルールに関しては相対インポートをエラーとするために追加しています。
```json:.eslintrc.json
{
  "extends": ["plugin:@typescript-eslint/recommended", "next/core-web-vitals"],
  "rules": {
    "no-restricted-imports": ["error", { "patterns": ["./", "../"] }]
  }
}

```

# Prettier設定
```shell
npm install --save-dev prettier
```

下記ファイルをプロジェクトルート下へ配置します。
デフォルト値でいいルールは記載していません。
```.prettierrc.json
{
  "singleQuote": true,
  "printWidth": 120,
  "jsxSingleQuote": true
}
```

npmコマンドを追加します。
```diff_json:package.json
"scripts": {
    "dev": "next dev",
    "build": "next build",
    "start": "next start",
    "lint": "next lint",
+   "format": "prettier --write --ignore-path .gitignore './**/*.{js,jsx,ts,tsx,json,css}' && next lint --fix"
  }
```

# Jest導入
```shell
npm install --save-dev jest jest-environment-jsdom @testing-library/jest-dom @testing-library/react @testing-library/user-event
```

package.jsonに記述を追加
```json:package.json
"scripts": {
    // 省略
    "test": "jest"
  }
```



# 参考記事
- [Next.js + TypeScript + ESLint + Prettier で開発環境を構築](https://blog.monorevo.jp/post-2104)
- [ESLint　相対インポートをエラーとする](https://www.ncaq.net/2018/07/18/12/01/24/)
- [【小規模サイト向け】Next.js ディレクトリ構成とコーディングルール](https://zenn.dev/necscat/articles/d5d9b7a3f859d7)
- [フロントエンド(Next.js)のテストについてまとめる](https://qiita.com/suzu1997/items/e4ee2fc1f52fbf505481)
- [Next.jsテスト](https://nextjs-ja-translation-docs.vercel.app/docs/testing)
- [Next.js13 + TypeScript + jestでコンポーネントの単体テストをする](https://zenn.dev/arsaga/articles/056e7196b41c08)
- [【新機能】Vercel Postgres + Next.js + PrismaでフルスタックWebアプリケーションを作ってみた](https://zenn.dev/msy/articles/8d991c79b739aa#api-route%E3%81%A7%E3%81%AEapi%E5%AE%9F%E8%A3%85)