Next.js

プロジェクト構成を理解する

7
  • 環境構築

create-next-app で App Router・TypeScript・src/ 構成のプロジェクトを作ると、最初は「ファイル多いな…どこ触るんだっけ?」となりがちです。この記事では、開発用 Docker ファイルを足したあとの フォルダの意味 をざっくり整理します。Next.js 16 系を前提に書いていますが、15 系でもほぼ同じ構成で読めます。

触る場所と、Git に入れる/入れないの境目だけ先に押さえておけば、次の機能追加で迷いにくくなります。

参考: Next.js — Project structure


目次

  1. 全体のツリー
  2. ざっくり3分類
  3. Docker ファイル(おさらい)
  4. アプリ本体(src と public)
  5. あとから増えるファイル
  6. 設定ファイル
  7. 環境変数
  8. 生成物と Git 除外
  9. リクエストが通る場所

全体のツリー

開発環境が揃ったあとのルートは、だいたい次の形です。

my-next-app/├── Dockerfile├── docker-compose.yml├── .dockerignore├── .env.example          # 共有用テンプレ(Git に入れる)├── .env.local            # ローカル専用(Git に入れない)├── .gitignore├── package.json├── package-lock.json├── tsconfig.json├── next.config.ts├── eslint.config.mjs├── README.md├── public/│   ├── next.svg│   └── ...└── src/    └── app/        ├── layout.tsx        ├── page.tsx        ├── page.module.css        ├── globals.css        └── favicon.ico

node_modules/.next/ は実行後にできますが、通常は Git に含めません。


ざっくり3分類

代表ファイル いつ触るか
Docker Dockerfile, docker-compose.yml, .dockerignore 環境を変えるとき(Node 版数、ポート、ボリューム)
アプリ src/app/**, public/** 画面・API を作るとき(日常はここ)
設定 package.json, tsconfig.json, next.config.ts 依存追加・ビルド設定・Lint のとき

日常の開発で編集するのは src/public/ が中心です。Docker ファイルは「環境の土台」として最初に置いて、あとはあまり触りません。


Docker ファイル(おさらい)

環境構築のあとに手動で足すのは Dockerfiledocker-compose.yml.dockerignore の3つだけです。

Dockerfile はコンテナ内で npm ci して next dev を起動するレシピです。-H 0.0.0.0 を付けないと、ホストのブラウザから繋がりません。docker-compose.yml はポート転送とソースのマウントを任せます。node_modules.next は匿名ボリュームに逃がして、ホストと中身が混ざらないようにしています。

.dockerignore はビルド時に node_modules.env.local をイメージへ送らないためのものです。全文や起動コマンドは環境構築の手順側の話で、画面を直すときは触らない土台 として置いておけば足ります。


アプリ本体(src と public)

src/app/ — App Router の入口

create-next-app--app--src-dir を付けた場合、ルートは src/app/ になります。

ファイル 役割
layout.tsx 全ページ共通の HTML 骨格・メタデータ・フォント
page.tsx / のページ本体(Server Component がデフォルト)
page.module.css page.tsx 専用の CSS Modules
globals.css サイト全体のベーススタイル
favicon.ico タブアイコン

あとから about/page.tsx を足せば /about が生えます。フォルダ=URL という App Router の基本は、この src/app/ 以下で決まります。

public/ — 静的ファイル

/next.svg のように URL パスそのまま で配信されるファイルを置きます。page.tsx では next/imagesrc="/next.svg" のように参照します。画像・favicon(app 配下に置く場合もある)・robots.txt など向きです。


あとから増えるファイル

初期状態にはありませんが、機能を足すと src/app/ 以下に次のようなファイルが増えます。いずれも ルートのフォルダに置く のが App Router の基本です。

ファイル 置き場所の例 役割
loading.tsx src/app/loading.tsx または about/loading.tsx ページ読み込み中の UI(Suspense 境界)
error.tsx src/app/error.tsx または about/error.tsx そのセグメント内のエラー UI
route.ts src/app/api/hello/route.ts HTTP API(Route Handler)。GET / POST などを export

about/page.tsx と同じ階層に about/loading.tsx を置けば /about 専用のローディング表示になります。API は page.tsx ではなく route.tsGETPOST を書きます。


設定ファイル

package.json / package-lock.json

依存関係と npm スクリプトです。

"scripts": {  "dev": "next dev",  "build": "next build",  "start": "next start",  "lint": "eslint"}

Docker 開発ではコンテナが npm run dev を実行します。package-lock.json があるので Dockerfile 側は npm ci が使えます。

tsconfig.json

TypeScript の厳しさやパスエイリアスを定義します。"@/*": ["./src/*"] により、src/ 直下を @/ で参照できます。

import styles from "@/app/page.module.css";

../../app/... のように階層を辿るより、@/components/Button のように書けるので、フォルダが深くなってから特に効いてきます。

next.config.ts

Next.js 本体の挙動(画像ドメイン、リダイレクトなど)を変えるファイルです。今の段階では触らなくて大丈夫です。

eslint.config.mjs

eslint-config-next を読み込み、App Router 向けの Lint ルールを有効にします。npm run lint で実行します。

README.md

プロジェクトの説明用です。create-next-app 標準のままでも動きますが、Docker で起動する手順を書いておくと clone した人が助かります。


環境変数

「Docker で Next.js の環境を構築する」の手順で、次の 2 ファイルを用意します。

ファイル Git 中身
.env.example 入れる キー名だけ(NEXT_PUBLIC_SITE_URL= など)
.env.local 入れない 開発用の値。空ファイルでも docker compose up は動く

.env.localdocker-compose.ymlenv_file でコンテナに渡されます。NEXT_PUBLIC_ だけブラウザに出る点は、ホストで next dev するときと同じです。作成手順は「Docker で Next.js の環境を構築する」の「環境変数」の節どおりです。


生成物と Git 除外

.gitignore で外しておくのが一般的なもの:

  • node_modules/npm ci / npm install で再生成できるので Git には入れません。
  • .next/next dev / next build の出力物です。
  • .env.local は秘密情報を含む可能性があるため除外します。
  • .env.example はキー名テンプレなので Git に入れます.env.local とは逆)。
  • next-env.d.ts は Next.js が自動生成するファイルです。

node_modules.next は Docker の匿名ボリュームでもコンテナ側に閉じ込めているので、ホストとコンテナで中身が混ざりにくくなっています。


リクエストが通る場所

ブラウザで http://localhost:3000/ を開いたときの流れです。

flowchart LR  Browser["ブラウザ"]  Compose["docker compose / port 3000"]  Dev["next dev(コンテナ内)"]  App["src/app/page.tsx"]  Public["public/ の静的ファイル"]  Browser --> Compose --> Dev --> App  Browser --> Compose --> Dev --> Public
  1. ホストの 3000 がコンテナの 3000 に転送される(docker-compose.yml
  2. コンテナ内の next dev がルート / を解決する
  3. src/app/page.tsx が HTML を返す。画像は public/ から配信

ページを直すときは src/app/page.tsx を編集して保存 すればよく、Docker を再起動する必要は通常ありません(ボリュームマウントとホットリロードのため)。


よくある勘違い

思いがち 実際
Dockerfile を直すたびにページが変わる 画面は src/app/。Docker は実行環境の話
public/page.tsx に置く ページは src/app/public/ は静的ファイル専用
.env を Git に入れる .env.local は除外。.env.example だけ共有
ルートに app/ がある --src-dir 指定時は src/app/

シェア