LoginSignup
1
0

【06】Next.js14でTodoアプリ作成(ディレクトリ構成修正編)

Posted at

はじめに

ディレクトリのベストプラクティスを知らずに、適当に開発してきたため、今一度ディレクトリ構成を見直すことにしました。

今までの記事

環境構築編

https://qiita.com/naoyuki2/items/e974c630c6cbd3c55254

【01】Next.js14でTodoアプリ作成(CREATE編)

https://qiita.com/naoyuki2/items/7474d448de7769905d82

【02】Next.js14でTodoアプリ作成(SELECT編)

https://qiita.com/naoyuki2/items/2d8ad09f767f818e8860

【03】Next.js14でTodoアプリ作成(INSERT編)

https://qiita.com/naoyuki2/items/27d550ab3766a1869aaf

【04】Next.js14でTodoアプリ作成(DELETE編)

https://qiita.com/naoyuki2/items/8fcb8ae5583a1aef8a2d

【05】Next.js14でTodoアプリ作成(UPDATE編)

https://qiita.com/naoyuki2/items/2d90cc092570dd5e6b73

今回のゴール

色々な記事を読んだ結果私は以下のようなディレクトリ構成にしました。

.
├── components/
│   ├── elements/
│   │   ├── Button.tsx
│   │   └── Input.tsx
│   └── layouts/
│       ├── Header.tsx
│       └── Footer.tsx
├── features/
│   └── todo/
│       ├── api/
│       │   ├── getTodo.ts
│       │   ├── postTodo.ts
│       │   ├── deleteTodo.ts
│       │   ├── patchTodo.ts
│       │   └── Index.ts
│       └── components/
│           ├── TodoInput/
│           │   └── TodoInput.tsx
│           ├── TodoList/
│           │   └── TodoList.tsx
│           ├── TodoItem/
│           │   └── TodoItem.tsx
│           └── Index.ts
└── src/app/
    ├── api/
    │   ├── lib/
    │   │   └── prisma.ts
    │   └── todo/
    │       ├── [id]/
    │       │   └── route.ts
    │       └── route.ts
    ├── favicon.ico
    ├── global.css
    ├── layout.tsx
    └── page.tsx

1.componentsディレクトリ

├── components/
│   ├── elements/
│   │   ├── Button.tsx
│   │   └── Input.tsx
│   └── layouts/
│       ├── Header.tsx
│       └── Footer.tsx

ルートディレクトリ直下に作成した/componentsでは、アプリケーション全体で使用されるコンポーネントを配置しています。

このレイヤーでは、副作用を持たずに親から受け取ったpropsのみを表示することに特化しています。
状態の受け取りに対して、条件分岐やクラスの付与などを行うことは問題ありません。

/components/elements

├── elements/
│   ├── Button.tsx
│   └── Input.tsx

ここでは、ページ全体で使用する小さい部品、いわゆるButtonInputなどを格納するディレクトリです。

/components/layouts

└── layouts/
    ├── Header.tsx
    └── Footer.tsx

ここでは、ページ全体で共通するレイアウト、いわゆるHeaderFooterを格納するディレクトリです。

2.featuresディレクトリ

├── features/
│   └── todo/
│       ├── api/
│       │   ├── getTodo.ts
│       │   ├── postTodo.ts
│       │   ├── deleteTodo.ts
│       │   ├── patchTodo.ts
│       │   └── Index.ts
│       └── components/
│           ├── TodoInput/
│           │   └── TodoInput.tsx
│           ├── TodoList/
│           │   └── TodoList.tsx
│           ├── TodoItem/
│           │   └── TodoItem.tsx
│           └── Index.ts

featuresは特定の機能をもっているコンポーネントをまとめるためのディレクトリです。

例に挙げている、TodoInputなどは、アプリケーション全体で再利用できるとは言えず、/componentsにいれず、featuresを用意しています。

featuresは日本語で特徴という意味なので、特徴あるコンポーネントを格納することから名付けけられたのではないでしょうか。

/features/todo/api

api/
│── getTodo.ts
│── postTodo.ts
│── deleteTodo.ts
│── patchTodo.ts
│── Index.ts

ここでは、todoに関するAPIをたたくための関数を格納しています。

前回の記事のpage.tsxを見てもらえればわかると思いますが、APIをたたくだけでもかなり記述量が増えてしまっていたためこのようにしました。

Index.tsについては後程解説します。

/features/todo/components

       └── components/
           ├── TodoInput/
           │   └── TodoInput.tsx
           ├── TodoList/
           │   └── TodoList.tsx
           ├── TodoItem/
           │   └── TodoItem.tsx
           └── Index.ts

ここでは、todoに関するコンポーネントを格納しています。

コンポーネントごとにフォルダを用意しているのは、その中に.styled.tsx.test.tsxstories.tsxなどを入れる可能性があるからだそうです。

私はテストもストーリーブックも分かりません。

ここでもIndex.tsがでてきます。次で解説します。

Index.ts

おまちかねIndex.tsの解説です。

意図としては、下記の記事のお言葉をお借りして説明させていただきます。

productstodoで置き換えてください。

● このファイルは、products関連のコンポーネントを一括でインポートするためのエントリーポイントとなります。
● コンポーネントのインポートパスを短くすることで、コードの可読性を向上させます。
● 他のファイルからこのエントリーポイントを通じてproductsコンポーネントにアクセスすることができます。
● 新しいproductsコンポーネントが追加された場合でも、このファイルの変更のみで済みます。

コード例を紹介すると以下の通りです。

features/todo/componentsIndex.ts
import TodoInput from './TodoInput/TodoInput'
import TodoList from './TodoList/TodoList'
import TodoItem from './TodoItem/TodoItem'

export { TodoInput, TodoList, TodoItem }
src/app/page.tsx
import * as Todo from '@features/todo/components/Index'

export default function Home() {
    return (
        <>
            <Todo.TodoInput />
            <Todo.TodoList />
        </>
    )
}

Index.tsでまとめてエクスポートしています。

そして、使用するページで* as Todoとすることで、Todo.TodoInputという風に使用します。

importするデータ量は増えてしまいますが、かなりわかりやすくなりますし、import文は一つで済みます。

APIをたたく関数もIndex.tsを使用してimportしています。

3.src/appディレクトリ

└── src/app/
    ├── api/
    │   ├── lib/
    │   │   └── prisma.ts
    │   └── todo/
    │       ├── [id]/
    │       │   └── route.ts
    │       └── route.ts
    ├── favicon.ico
    ├── global.css
    ├── layout.tsx
    └── page.tsx

私はプロジェクトを作る際にsrcフォルダの有無を有りにしたので、srcフォルダがありますが、別にいらないような気がします。

ここはそんなに解説することはないですね。

おわりに

このディレクトリ構成が一番!なんてものはないと思いますが、私は個人開発ではこのディレクトリ構成で開発を進めようと思います。

次回以降はまたロジックを実装していきます。

参考文献

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0