Pathee engineering blog

世界をしなやかに変えるエンジニアたちのブログ

フルスタックNext.jsアプリケーションのディレクトリ構成 | Pathee Advent Calendar 2021 Day 3

これはPathee Advent Calendarの3日目の記事です

こんにちは。土田です。

前回STORECAST Managerのお話をさせていただきましたが、

今回は、フルNext.jsのアプリケーションで、どういったディレクトリ構成を取って開発しているのかをお話させていただきます。

ディレクトリ構成

早速ですが、Next.jsアプリケーションのプロジェクト配下でtree出力した、主要なディレクトリは以下になります。

.
├── infra
│   ├── docker
│   └── mysql
│       ├── conf.d
│       ├── original
│       └── sql
├── public
│   └── static
│       ├── fonts
│       └── images
└── src
    ├── @types
    ├── assets
    ├── components
    │   ├── gui
    │   │   ├── alerts
    │   │   ├── atoms
    │   │   ├── buttons
    │   │   ├── forms
    │   │   └── tables
    │   ├── layouts
    │   └── pages
    ├── constants
    ├── hooks
    ├── libs
    ├── pages
    │   ├── api
    │   │   ├── auth
    │   │   ├── manager
    │   │   └── st
    │   ├── auth
    │   └── manager
    ├── server
    │   ├── domains
    │   │   └── manager
    │   ├── entities
    │   │   ├── manager
    │   │   └── st
    │   │       └── XXXX
    │   ├── migrations
    │   │   └── manager
    │   ├── repositories
    │   │   ├── manager
    │   │   └── st
    │   │       └── XXXX
    │   └── subscribers
    │       └── manager
    ├── states
    ├── styles
    └── utils

役割ごとに色分けをすると、このようになります。

f:id:pathee:20211203130727p:plain

順に役割を上げていきます。

1. 開発用インフラ設定の各ディレクト

上から話していくと、一番アプリケーションと縁遠いディレクトリからになってしまってあれですが、 infraディレクトリはローカル開発で利用するインフラの設定を配置しています。

docker

dockerディレクトリにはdocker-compose.ymlから見るenv_fileを配置しています。
Next.jsはローカル起動用の環境変数を、ルートディレクトリに配置した.env.localファイルから読み取ってくれるのですが、 .env.localファイルはリポジトリ管理しないファイルにしているので、これをenv_fileに指定していると、 git cloneの後、無邪気にdocker compose up -dを実行すると、起動に失敗してしまいます。

それはそれで良い気もしますが、.env.localファイルを作るためのアプリケーション用環境変数ファイル(.env)には、コンテナ自体に必要な環境変数が書かれているわけでもないと思うので、 起動前に読み込む環境変数ファイルは別管理にしました。

ちなみに起動用のファイル(infra/docker/.env.dev)の内容は、以下の通りです。

NODE_ENV="development"
REACT_EDITOR=atom

mysql

mysqlディレクトリは、mysqlコンテナから読み込む各種ファイルを置いておく場所として利用しています。

2. フロントエンド用ディレクト

Next.jsは元々フロントエンド用のフレームワークなので、他は大体フロントエンド用になっています。

Next.js関連のディレクトリについて

publicディレクトリは、Next.jsで静的ファイルを配信する場合に利用するディレクトリです。

nextjs-ja-translation-docs.vercel.app

srcディレクトリ配下のpages、stylesもNext.js関連のディレクトリなため、それ以外について説明していきます(stylesは必須なわけではありませんが)。

@types

型定義用のディレクトリです。
主にAPIコールで受け渡しに利用する型など、複数箇所から利用する型を定義するのに利用しています。

assets

next/imageで遅延読み込みする画像ファイルなどを配置する場所として利用しています。

components

さて、componentsディレクトリですが、大きく3つの用途で利用しています。

現状ではAtomic Designの構成は冗長で、利用しづらいと判断したため、このような構成になっています。

components/gui

guiディレクトリの中は、大まかなタグ要素で分類しています。
例えば、input要素はformsに、ボタン系はbuttonsに配置し、各ディレクトリにinput.tsを置いて、

export * from './SaveButton';

のような記載をしています。

あまり使わないですが、各パーツから共通的に参照する可能性のある最小のパーツは、atomsディレクトリに配置するようにしています。

components/layouts

layoutsディレクトリは、ページで共通で利用するレイアウトのためのディレクトリです。
アプリケーションの標準レイアウトはlayouts直下で、それ以外の個別レイアウトは更にサブディレクトリを切って管理しています。

mainディレクトリを切ってもよかったかなぁとは思います。

STORECAST Managerでは例えば以下のようにレイアウトが異なるため、それぞれ分けて持つようにしています。

  • layouts/index.tsの適用例
    f:id:pathee:20211203144238p:plain:w400

  • layouts/auth/index.tsの適用例
    f:id:pathee:20211203144225p:plain:w400

components/pages

src/pages配下で利用する、各ページ専用のコンポーネントを配置する場所としています。
サブディレクトリは、src/pagesディレクトリと同じような切り方をするようにしています。

例えば、src/pages/st/accounts/[id]用のpagesディレクトリは、src/components/pages/st/accounts/[id]になっています。

constants

アプリケーションで利用する定数を定義する場所として利用しています。

hooks

カスタムフックを配置するディレクトリです。

libs

主に環境変数を利用する、ライブラリの設定処理を記載しています。

states

recoilで利用するstateを配置するディレクトリです。

utils

汎用的なユーティリティ処理を配置するディレクトリです。

3. バックエンド用ディレクト

serverディレクトリは、src/pages/api配下の処理で使われる、バックエンド用のコードディレクトリです。

domains

src/pages/apiから直接呼び出されるのは、このdomains配下のみになるように実装しています。

例えば、pages/api/accountsから呼び出されるのは、domains/accounts.tsのようにして利用しています。

repositories

順番が前後しますが、repositoriesディレクトリはDBへのアクセス処理を書く場所として利用しています。

repositories直下のディレクトリはDB名で、その配下にテーブル名のコードを配置しています。

  • 例:src/server/repositories/manager/account.tsであれば、managerDBのaccountテーブル

STORECAST自体は複数のDBを持つので、stディレクトリ配下に更にDB名でサブディレクトリを切る構成にしています。

entities、migrations、subscribers

entities、migrations、subscribersはTypeORM関連のディレクトリです。
公式ドキュメントそのままの場合は、entity/migration/subscriberですが、プロジェクト内の他のディレクトリに合わせて複数形にしています。

typeorm.io

まとめ

以上が現状のディレクトリ構成になっています。 アプリケーションを作っていくうちに、また構成が変わるかもしれませんが、最初の段階としては管理しやすいのでおすすめです。