Next.js ディレクトリ設計
TL;DR
- __tests__
- components // アプリケーション全体で共有されるコンポーネントを定義
- config // アプリケーションで使用される設定ファイルを管理
- features // featureごとにモジュールを管理
- auth
- api
- components
- types
- layouts // ページごとに異なるLayoutを定義
- lib // アプリケーションで使用されるライブラリを管理
- pages // Next.jsのページを管理
- providers // Context APIのProviderを管理
- stores // Globalに管理するStateを定義
- testing // テストに関連するファイルを管理
- types // アプリケーション全体で使用されるTypeScriptの型定義を管理
- utils // ユーティリティ関数を管理
featuresディレクトリ
features/auth
- api // API関連のファイルを管理
- components // featureに関心のあるcomponentを管理
- types // 型定義
- index.ts // 外部に公開するもののみを選択してexportする
package by layerとpackage by feature
Bad
- components
- User
- UserCard.tsx
- UserList.tsx
- hooks
- useUsers.ts
- pages
- users
- [id].tsx
- index.tsx
- services
- userService.ts
- types
- User.ts
- utils
- formatUserDate.ts
こちらのディレクトリ設定の何が問題なのかというと、「ユーザー管理」機能に関連するファイルが分散していることです。
例えば、以下の機能を改修したいとします。
- ユーザーAPIのエンドポイントを変更する
- ユーザーAPIのレスポンスを加工する
- ユーザーのUIを変更する
この時に、hooksやservicesなどプロジェクト全体を探し回る必要がありコストがかかります。もし、これらのファイルが一つのフォルダ(users)にまとめられていれば、探すコストがかかりません。 また、特定の機能に関する変更が複数のレイヤーにまたがるため、変更の影響範囲が広がりやすいです。
こちらのディレクトリ設計は、componentsやhooks、servicesといった技術的なレイヤーの単位で分けられています。 この設計を「package by layer」と呼びます。他にも、技術駆動パッケージングとも呼ばれます。
Good
- features
- users
- components
- UserCard.tsx
- UserList.tsx
- hooks
- useUsers.ts
- pages
- [id].tsx
- index.tsx
- services
- userService.ts
- types
- User.ts
- utils
- formatUserDate.ts
良いコードの例です。こちらは「ユーザー管理」機能に関連するファイルが一つのフォルダ(features/users)にまとめられています。そのため、対象のファイルを探すコストがかかりません。 この設計を「package by feature」と呼びます。
参考
- https://zenn.dev/mybest_dev/articles/c0570e67978673
- https://zenn.dev/misuken/articles/bdd33790ed4cd0
- https://zenn.dev/pandanoir/articles/d74d317f2b3caf
- https://zenn.dev/miyamonz/articles/fa0f77b6cecf61
- https://qiita.com/taisei-13046/items/64f764ad2d2caaf4d7d4
- https://github.com/PacktPublishing/React-Application-Architecture-for-Production/tree/main/code-stages/chapter-09/src