NextJSとの併用
NextJSプロジェクトでFSDを実装することは可能ですが、プロジェクトの構造に関するNextJSの要件とFSDの原則の間に2つの点で対立が生じます。
pagesのファイルルーティング- NextJSにおける
appの対立、または欠如
pagesにおけるFSDとNextJSの対立
NextJSは、アプリケーションのルートを定義するためにpagesフォルダーを使用することを提案しています。pagesフォルダー内のファイルがURLに対応することを期待しています。このルーティングメカニズムは、FSDの概念に適合しません。なぜなら、このようなルーティングメカニズムでは、スライスの平坦な構造を維持することができないからです。
NextJSのpagesフォルダーをプロジェクトのルートフォルダーに移動する(推奨)
このアプローチは、NextJSのpagesフォルダーをプロジェクトのルートフォルダーに移動し、FSDのページをNextJSのpagesフォルダーにインポートすることにあります。これにより、srcフォルダー内でFSDのプロジェクト構造を維持できます。
├── pages # NextJSのpagesフォルダー
├── src
│ ├── app
│ ├── entities
│ ├── features
│ ├── pages # FSDのpagesフォルダー
│ ├── shared
│ ├── widgets
FSD構造におけるpagesフォルダーの名前変更
もう一つの解決策は、FSD構造内のpages層の名前を変更して、NextJSのpagesフォルダーとの名前衝突を避けることです。
FSDのpages層をviews層に変更することができます。
このようにすることで、srcフォルダー内のプロジェクト構造は、NextJSの要件と矛盾することなく保持されます。
├── app
├── entities
├── features
├── pages # NextJSのpagesフォルダー
├── views # 名前が変更されたFSDのページフォルダー
├── shared
├── widgets
この場合、プロジェクトのREADMEや内部ドキュメントなど、目立つ場所にこの名前変更を文書化することをお勧めします。この名前変更は、「プロジェクト知識」の一部です。
NextJSにおけるappフォルダーの欠如
NextJSのバージョン13未満では、明示的なappフォルダーは存在せず、代わりにNextJSは_app.tsxファイルを提供しています。このファイルは、プロジェクトのすべてのページのラッピングコンポーネントとして機能しています。
pages/_app.tsxファイルへの機能のインポート
NextJSの構造におけるappフォルダーの欠如の問題を解決するために、app層内にAppコンポーネントを作成し、NextJSがそれを使用できるようにpages/_app.tsxにAppコンポーネントをインポートすることができます。例えば
// app/providers/index.tsx
const App = ({ Component, pageProps }: AppProps) => {
return (
<Provider1>
<Provider2>
<BaseLayout>
<Component {...pageProps} />
</BaseLayout>
</Provider2>
</Provider1>
);
};
export default App;
その後、Appコンポーネントとプロジェクトのグローバルスタイルをpages/_app.tsxに次のようにインポートできます。
// pages/_app.tsx
import 'app/styles/index.scss'
export { default } from 'app/providers';
App Routerの使用
App Routerは、Next.jsのバージョン13.4で安定版として登場しました。App Routerを使用すると、pagesフォルダーの代わりにappフォルダーをルーティングに使用できます。
FSDの原則に従うために、NextJSのappフォルダーをpagesフォルダーとの名前衝突を解消するために推奨される方法で扱うべきです。
このアプローチは、NextJSのappフォルダーをプロジェクトのルートフォルダーに移動し、FSDのページをNextJSのappフォルダーにインポートすることに基づいています。これにより、srcフォルダー内のFSDプロジェクト構造が保持されます。また、プロジェクトのルートフォルダーにpagesフォルダーを追加することもお勧めします。なぜなら、App RouterはPages Routerと互換性があるからです。
├── app # NextJSのappフォルダー
├── pages # 空のNextJSのpagesフォルダー
│ ├── README.md # このフォルダーの目的に関する説明
├── src
│ ├── app # FSDのappフォルダー
│ ├── entities
│ ├── features
│ ├── pages # FSDのpagesフォルダー
│ ├── shared
│ ├── widgets