この記事は Next.js公式ドキュメント『Project Organization and File Colocation 』の翻訳記事です。
Next.js 公式ドキュメントは日本語翻訳プロジェクトがかつてありましたが更新が止まっており、(React・Next.jsアプリケーションの設計について考えたいという動機で)ちゃんと読みたかったこちらの記事を個人的に翻訳しました。
この記事の中で「コロケーション」という用語が繰り返し出てきますが、さまざまなReact関連のドキュメントで言及があり、(旧版)React公式ドキュメントの『ファイル構成』、 Kent C. Dodds 氏のブログ記事『Colocation』(日本語版はこちら 『コロケーション』)、bulletproof-reactの『Component Best Practices』においては、それぞれ次のように言及されています。
すべて1フォルダに入れるところから始めましょう。そのうち十分に数が増えれば、いくつかのファイルを分離したくなってくるでしょう。そのころには、どのファイルを一緒に編集している頻度が高いのか、十分わかるようになっているでしょう。一般的には、よく一緒に変更するファイルを近くに置いておくのは良いアイディアです。この原則は、「コロケーション」と呼ばれます。
コロケーションの概念はこの基本的な原則に集約されます:
"可能な限り関連性が高いものの近くにコードを置いてください。"
こうも言えます: "一緒に変化するものは、合理的な範囲で近くに置くべきです。"と。
引用: コロケーション
Components Best Practices
Colocate things as close as possible to where it's being used(使用箇所のなるべく近くに配置する)
Keep components, functions, styles, state, etc. as close as possible to the component where it's being used. This will not only make your codebase more readable and easier to understand but it will also improve your application performance since it will reduce redundant re-renders on state updates.(コンポーネント、関数、スタイル、ステートなどは、それらが使用されるコンポーネントのできる限り近くに置きましょう。これにより、コードベースがリーダブルかつ理解しやすくなるだけでなく、ステート更新時の余計な再レンダリングが減るため、アプリケーションのパフォーマンスも向上します。)
以下、翻訳記事となります。
Next.jsのプロジェクト構成とファイルコロケーション
Next.jsは、ルーティングフォルダ・ファイル規約以外では、プロジェクトのファイルをどのような構成にしコロケーションするかについて、 何か特定の方法を推奨しているわけではありません。
このページでは、Next.jsのプロジェクト構成に役立つ、Next.jsのデフォルト動作と機能を紹介します。
デフォルトの安全なコロケーション
app
ディレクトリ内では、ネストされたフォルダの階層 がルート構造を定義します。
app
ディレクトリ内の各フォルダは、ルートセグメント(Route Segments)です。各ルートセグメントは、URLパス内の対応するセグメントにマップされます。
しかし、フォルダによってルート構造が定義されているにもかかわらず、 page.js
または route.js
ファイルがルートセグメントに追加されるまでは、ルートは 公開されていない状態であり、アクセスすることはできません 。
ルートが公開されてアクセスできるようになったとしても、page.js
または route.js
によって 返却されるコンテンツ (page.js
と route.js
に記述されている内容)だけがクライアントに送信されます。
これは、app
ディレクトリ内の プロジェクトファイル が、間違えてルーティング可能になってしまうことがなく、ルートセグメント内で 安全にコロケーションする ことができるということを意味します。
知っておくと良いこと
- これは、App Router の
app
ディレクトリが、Pages Router のpages
ディレクトリと異なっている点です。Pages Router ではpages
ディレクトリ内のいずれのファイルもルートとして扱われます。 -
app
ディレクトリ内にプロジェクトファイルをコロケーションすることができると話しましたが、これは必須というわけではありません。あなたの好みの方法に応じて、app
ディレクトリの外にプロジェクトファイルを置いてもよいでしょう。
プロジェクト構成のための機能
Next.jsは、プロジェクト構成を行うのに役立つさまざまな機能を提供しています。
プライベートフォルダ(Private Folders)
プライベートフォルダは、フォルダのプレフィックスとしてアンダースコアを付けることで作成できます: _folderName
これは、フォルダがプライベートな実装の詳細であり、ルーティングシステムによって考慮されるべきではないということを表します。そのため、 プライベートフォルダおよびそのすべてのサブフォルダはルーティングから除外されます。
app
ディレクトリ内のファイルは デフォルトで安全にコロケーションする ことができるため、コロケーションのためにプライベートフォルダにすることが必須なわけではありません。しかし、プライベートフォルダは以下の目的のために役立つでしょう:
- UIのロジックとルーティングのロジックを分離したいとき
- プロジェクトとNext.jsのエコシステムにおいて内部ファイルを一貫した方法で整理したいとき
- コードエディタ上でファイルをソートしたりやグルーピングしたいとき
- 将来的なNext.jsのファイル規約と命名がコンフリクトする可能性を回避したいとき
知っておくと良いこと
- フレームワークの規約とは関係ありませんが、プライベートフォルダの外のファイルでも同じようにアンダースコアを使ってそれを「プライベートなファイルである」として扱ってもよいでしょう。
- アンダースコアで始まるURLセグメントを作成するには、フォルダ名の前に
%5F
(アンダースコアのURLエンコード形式)を付けてください:%5FfolderName
。 - プライベートフォルダを使用しない場合、偶然の命名のコンフリクトを防げるように、Next.jsの特別なファイル命名規則を知っておくとよいでしょう。
ルートグループ(Route Groups)
ルートグループは、フォルダを括弧で囲むことで作成できます: (folderName)
。
これは、そのフォルダは構成を表すという目的のために使用されているのでルートのURLパスには 含めるべきではない 、ということを示しています。
ルートグループは以下の目的のために役立つでしょう:
- ルートをグループに整理するため。例: サイトのセクション単位、目的単位、チーム単位など。
- 同じルートセグメントレベルでのネストされたレイアウトを有効にする:
srcディレクトリ
Next.jsは、アプリケーションコード(app
を含む)をオプションの src
ディレクトリ内に置くことをサポートしています。これにより、アプリケーションコードは、主にプロジェクトルートに存在するプロジェクトの設定ファイルと分離されます。
モジュールパスエイリアス(Module Path Aliases)
Next.jsは、深くネストされたプロジェクトファイル全体でのインポートを読みやすく保守しやすくするためのモジュールパスエイリアスをサポートしています。
// before
import { Button } from '../../../components/button'
// after
import { Button } from '@/components/button'
プロジェクト構成の戦略
Next.jsプロジェクトでフォルダ・ファイル構成の方法について話すとき、「正しい」方法や「間違った」方法というものはありません。
以下のセクションでは、一般的な戦略の超概要レベルだけをいくつか示しています。最も基本的かつ簡潔なポイントとしては、あなたやあなたのチームに合った戦略を選び、それがプロジェクト全体で一貫している、ということです。
知っておくと良いこと
- 下記の例では、
components
やlib
フォルダを一般的なプレースホルダとして使用していますが、これらの命名がNext.jsフレームワークにおいて特別な機能や役割を持っているわけではありません。あなたのプロジェクトでは、ui
、utils
、hooks
、styles
など他のフォルダを使用するかもしれません。
app
の外にプロジェクトファイルを置く
この戦略では、すべてのアプリケーションコードを プロジェクトルート の共有フォルダに置き、appディレクトリは単なるルーティング目的のためだけに使用します。
app
のトップレベルフォルダ内にプロジェクトファイルを置く
この戦略では、すべてのアプリケーションコードを app
ディレクトリルート の共有フォルダに置きます。
機能やルートごとにプロジェクトファイルを分割する
この戦略では、グローバルに共有されるアプリケーションコードを app
ディレクトリルートに置き、それを使用するルートセグメントにより特定のアプリケーションコードを 分割 します。