Next.jsのフォルダ構成を考えよう! 〜 アトミックデザイン編 〜

開発プロジェクトのフォルダ構成って毎回悩みますよね。

プロジェクトやチーム、個人の設計思想によってかなり違ってきますし、プロジェクトのフェーズ(序盤・中盤・終盤)によっても「使いにくいフォルダ構成だな」「もっとこうしておけば良かった…」というように考え方が変わったりします。

考え始めると意外と難しいものではありますが、フォルダ構成について悩むのもソフトウェア開発の醍醐味で、プロジェクト立ち上げ時のワクワクを感じるひとつの楽しみでもあると思います。

そんなフォルダ構成について、今回はNext.jsプロジェクトにおけるフォルダ構成アトミックデザインをベースとして考えてみました。

目次

先に結論

調べたり考えたりした結果、個人的には以下の構成が良いなとなりました。

next/
|-- __tests__/
|   |-- api/
|   |-- components/
|   |   |-- atoms/
|   |   |-- molecules/
|   |   |-- organisms/
|   |   `-- templates/
|   |-- hooks/
|   |-- lib/
|   `-- pages/
|       `-- api/
|-- public/
`-- src/
    |-- api/
    |-- components/
    |   |-- atoms/
    |   |-- molecules/
    |   |-- organisms/
    |   `-- templates/
    |-- hooks/
    |-- lib/
    |-- pages/
    |   `-- api/
    |-- theme/
    `-- types/

src,__tests__を一括で作るコマンドはこちら。

mkdir -p __tests__ __tests__/api __tests__/components __tests__/components/atoms __tests__/components/molecules __tests__/components/organisms __tests__/components/templates __tests__/hooks __tests__/lib __tests__/pages __tests__/pages/api src src/api src/components src/components/atoms src/components/molecules src/components/organisms src/components/templates src/hooks src/lib src/pages src/pages/api src/theme src/types 

Next.jsなところ

まずNext.jsではpages配下が自動的にルーティングされる部分。

基本的に変更しようがない部分ではありますし、変更する意味もなさそうです。create-next-appするとpages,pages/apiが作成されますが、これはそのままで良いと思います。

しかし、

  • コードの肥大化を防ぐ
  • 再利用しやすいコードにする

ということは意識していきたいです。

そのため、pagesはNext.jsアプリケーションのエントリポイントとしての役割のみを持たせ、詳細な実装は別フォルダへ委譲します。
pages配下のソースコードからは別フォルダのソースコードをimportして呼び出すくらいになるのが理想です。

あとはどこで管理するかくらいですが、最終的に以下のようにすることにしました。

  • APIの詳細部分は単純にapiにまとめる
  • UIの詳細部分はcomponentsにまとめる(後述のアトミックデザインにならう)

UIコンポーネント

UIの詳細はアトミックデザインにならって以下のような構成にします。

components/
|-- atoms/
|-- molecules/
|-- organisms/
`-- templates/

アトミックデザインを採用する理由は、Reactのようなコンポーネント主体のライブラリアトミックデザインの設計思想との親和性が高いと考えるからです。

UIパーツを細分化して、大きなものは小さなものの集合という構成はわかりやすくて良いです。

アトミックデザインの詳細については、さまざまなサイトで解説されていること、考案者のBrad Frost氏によってそのドキュメントがWeb上で公開されていることから省きます。

参考リンク

Reactなところ

UIコンポーネントについてはすでに書いた通り。

React関連で残すところは、フック(hook)スタイル状態管理くらいでしょうか?

hook

これは単純にhooksで良さそう。
Reactを使っていることがパッとわかるのも良いです。

スタイル

ReactのコンポーネントライブラリとしてChakra UIを使うことが多いので、スタイル関連はthemeへまとめています。

ただし、Chakra UIのようなコンポーネントライブラリを使わない場合はstylesがわかりやすいかなと思います。

状態管理

フロントエンド側では状態管理する必要がないような設計が好みなのであまりきちんと調べず。

必要に応じて、使用する状態管理ライブラリに合わせたフォルダを作れば良いかなと思います。

フォルダ名はライブラリによって変わると思うので割愛。

共通処理・共通定義

言語やフレームワークにはあまり依存しないところとして、共通処理型定義が考えられます。

共通処理

共通処理はどんなプロジェクトでも用意するかと思います。

いろいろ考えた結果、共通処理はlibにまとめるのが良いかなと思います。

今まで携わったプロジェクトではutilcommonが多かったのですが、

  • util/util.jscommon/common.jsのような同じ名前が2重に続くファイルが作られがち。
  • util.jscommon.jsとりあえずでなんでも書いてしまう人がいる。
  • 上記のファイルが編集しやすく、複数人で編集するため肥大化する・競合しやすい

ということが多くて嫌でした。

なので誰でも使いやすい名前は避けるべきかなという思いがあります。
特に「とりあえず」で編集しやすいファイルはなくしたいです。

libという名前をベースとすると、lib.jsは意味がわからないので作られにくそうですし、lib/util.jsも変なので作られにくそう。

libという名前からイメージするのがライブラリやモジュールなので、lib配下は意味のある単位でファイルを分割して作ってくれそうだなという独断と偏見からlibを推したいと思います。

型定義

独自の型定義を別ファイルにするような言語の場合は、typesにまとめておきます。

TypeScript由来なところはありますが、わかりやすくて良いなと感じています。

ユニットテスト

__tests__配下で行うテストはユニットテストです。

ソースコードごとにテストすることを想定しているため、基本的にはsrcと同様の構成がわかりやすいかなと考えています。

機能ベースでテストするなど、テスト対象がある程度まとまりを持ったものとなる場合は、違うフォルダ構成にすべきかなというところです。

最後に

フォルダ構成と書くとなんか簡単そうな響きですが、考え出すとなかなか難しいところ。

「そんなの適当でいい」という人も多いかもしれませんが、チーム開発をする場合には管理しやすいフォルダ構成にするのは必須事項というのが筆者の意見です。(個人で開発する分には適当でよいかもしれませんが)

最終的にはチーム内ですり合わせをして、共通理解・共通認識を持つことができればどんなフォルダ構成でもOKだと思いますが、ベースとなる考え方がひとつあるだけでも検討しやすいかと思います。

よかったらシェアしてね!
  • URLをコピーしました!
目次