🛠️
DockerでNext.jsの環境構築をする
はじめに
DockerでNext.jsの環境構築を行いました
- Next.js
- TypeScript
- ホットリロード機能
- ESLintの設定
- Prettierの設定
 
最終的なディレクトリ構成
.
├── .vscode
│   └── .settings.json
├── src
|   ├── <Next.jsのコード>
|   ├── .eslintrc.json
│   └── .prettierrc
├── .dockerignore
├── docker-compose.yml
└── Dockerfile
Next.js on Docker
Dockerfile
Dockerfile
FROM node:lts-buster-slim
WORKDIR /app
docker-compose.yml
docker-compose.yml
version: '3'
services:
  app:
    build:
      context: .
    tty: true
    volumes:
      - ./src:/app
    ports:
      - "3000:3000"
    command: sh -c "npm run dev"
- volumes
- srcディレクトリ内にNext.jsアプリを作成していくため、./src:/appとしています
 
- srcディレクトリ内にNext.jsアプリを作成していくため、
create-next-app
docker-compose build
docker-compose run --rm app sh -c 'npx create-next-app src --typescript'
docker-compose up
これでアプリの雛形をsrcディレクトリ内に作成でき、サーバーを起動できていることが確認できました
ホットリロードの設定
Next.jsのホットリロード機能を有効にするため、docker-compose.ymlで環境変数を設定しました
docker-compose.yml
version: '3'
services:
  app:
    build:
      context: .
    tty: true
    volumes:
      - ./src:/app
    ports:
      - "3000:3000"
+   environment:
+     - WATCHPACK_POLLING=true
    command: sh -c "npm run dev"
- 
- webpackに含まれているライブラリ
- fileを監視する役割
 
- 
ちなみに、最初はnext.config.jsに以下のような watchOptionsを記載するやり方を真似したのですが、採用しませんでした
next.config.js
module.exports = {
  webpackDevMiddleware: config => {
    config.watchOptions = {
      poll: 800,
      aggregateTimeout: 300,
    }
    return config
  },
}
採用しなかった理由としては以下です
- コード変更から一定時間たたないとホットリロードによる変更が開始しない(poll: <秒数>のため)
- ホットリロードが完了するのに数秒かかる(再コンパイルが発生するため?)
リンター・フォーマッターの設定
そもそもなぜESLintだけでなくPrettierも使用するのか、といったことに疑問を持ったのですが、以下の記事が参考になりました
まとめると、
- ESLintで整形しきれない部分をPrettierが補える
- ESLintよりPrettierの方が手軽で確実に整形できる
とのことでした
ESLintの設定
- ESLint
- Next.jsでのESLint
をインストールします
docker-compose run --rm app npm i --save-dev eslint eslint-config-next
- 上記コマンドを実行すると対話形式で.eslintrc.jsonが作成されました
- 以下の記事を参考にしました
 
ESLintファイルの修正
- Prettierを導入するために追記
- Prettierとのルールが重複する部分はESLint側で無効化
 
- ESLintでエラーが出る箇所を修正
- ファイルでReactを必ずimportするというルールを無効化
 
- importするライブラリなどをアルファベット順にする
.eslintrc.json
{
  "env": {
    "browser": true,
    "es2021": true
  },
  "extends": [
    "plugin:react/recommended",
    "standard",
+   "prettier" // eslintとprettierの衝突回避
  ],
  "parser": "@typescript-eslint/parser",
  "parserOptions": {
    "ecmaFeatures": {
      "jsx": true
    },
    "ecmaVersion": "latest",
    "sourceType": "module"
  },
  "plugins": ["react", "@typescript-eslint"],
  "rules": {
+   "react/react-in-jsx-scope": "off", // v17からReactをimport不要になった
+   // importをアルファベット順にする
+   "import/order": [
+     "error",
+     {
+       "alphabetize": {
+         "order": "asc"
+       }
+     }
+   ]
  }
}
Prettierの設定
- prettier
- eslint-config-prettier
をインストールします
docker-compose run --rm app npm i --save-dev prettier eslint-config-prettier
- 上記コマンドを実行した後、.prettierrcをルートディレクトリに作成します
- Prettierの設定一覧は以下の記事を参考にしました
 
Prettierの設定は完全に個人の好みですが、載せておきます
.prettierrc
{
  "singleQuote": false,
  "jsxSingleQuote": false,
  "semi": false,
  "trailingComma": "all",
  "arrowParens": "always"
}
VSCodeでのリンター・フォーマッターの設定
拡張機能のインストールと./.vscode/settings.jsonでの設定を行いました
- 拡張機能
- ESLint
- リアルタイムでESLintでのエラーを表示
- 保存と同時に修正(settings.jsonに追記)
 
- Prettier
- 保存と同時に修正(settings.jsonに追記)
 
 
- ESLint
./.vscode/settings.json
{
  // ESLint
  "editor.codeActionsOnSave": {
    "source.fixAll": true
  },
  // Prettier
  "editor.defaultFormatter": "esbenp.prettier-vscode",
  "editor.formatOnSave": true,
}
おわりに
Next.jsでの基本的な環境構築はできたかなと思います。
アプリを作るたびに上記の手順をいちいち行っていくのは面倒くさいので、テンプレート化したいなと思いました。
参考
- Next.js on Docker
- ホットリロード(TypeScript)
- ESLint&Prettier





Discussion
とてもわかりやすくご説明くださり、ありがとうございます。
docker-composeにポートの情報を載せても良いかもしれません。(ご存知だとは思われますが、ローカルホストなどでフロントをすぐに確認することができます。)
ご指摘ありがとうございます
上記に関して、追記させていただきました