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