機能ベースのフォルダー構成
型ではなく機能ドメイン単位でコードを整理し、テスト、スタイル、コンポーネントを近くに配置して、eslint-plugin-boundariesで境界を強制します。
「機能ベースのフォルダー構成」はCoddyKit上の無料Frontend Academyレッスンです。 これはレッスン4/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはFrontend Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Frontend Academyコースには全4レッスンが含まれています。
コードを整理する2つの方法
コードは種類別(components/、hooks/、services/、types/)にも、機能別(auth/、checkout/、dashboard/。それぞれに独自のcomponents、hooksなどを含める)にもまとめられます。中規模から大規模のアプリでは、機能別の構成が優れています。
種類別構成 — デフォルトの罠
典型的なReactチュートリアルの構成では、すべてを種類別にまとめます。しかし、この構成は規模の拡大に弱いという問題があります。ファイルを1つ変更するたびに、関係のない複数のフォルダーに触れることになり、「checkoutのコードをすべて見つける」にはツリー全体をgrepしなければなりません。
// Type-based (avoid for large apps):
src/
components/
Button.tsx
LoginForm.tsx
CartItem.tsx
hooks/
useAuth.ts
useCart.ts
services/
auth.ts
cart.ts
types/
User.ts
CartItem.ts機能別の構成
1つの機能に関連するものをすべて1つのフォルダーにまとめます。見つけやすく、削除しやすく、構造を理解しやすい方法です。
src/
features/
auth/
LoginForm.tsx
SignupForm.tsx
useAuth.ts
auth.service.ts
auth.types.ts
auth.test.tsx
cart/
CartItem.tsx
CartSummary.tsx
useCart.ts
cart.service.ts
cart.types.ts
shared/
components/
Button.tsx
hooks/
useDebounce.ts機能内でのコロケーション
機能フォルダーには、components、hooks、services、types、testsなど、そのドメインに必要なすべてのコードを含めます。新しい開発者がauthの仕組みを理解したい場合は、auth/を開けば済みます。authを削除したい場合は、そのフォルダーを削除します。
共有コードと機能固有コード
2つ以上の機能で使用するコードはshared/(またはlib/)に移します。1つの機能だけで使用するコードは、その機能内に残します。「将来再利用するかもしれない」という理由だけで切り出すのは避け、2回目に使用するときまで待って抽出してください。
機能の境界に関するルール
機能同士が直接インポートし合わないようにします。2つの機能でコードを共有する必要がある場合は、共有部分をshared/に移します。連携が必要な場合は、イベントまたはアプリレベルの共有ストアを使用します。
ESLintで境界を強制する
eslint-plugin-boundariesまたはeslint-plugin-importを使用して、機能からsharedへのインポートは許可し、機能同士のインポートは禁止するルールを強制します。
// .eslintrc.json
{
"plugins": ["boundaries"],
"settings": {
"boundaries/elements": [
{ "type": "feature", "pattern": "src/features/*" },
{ "type": "shared", "pattern": "src/shared/*" }
]
},
"rules": {
"boundaries/element-types": ["error", {
"default": "disallow",
"rules": [
{ "from": "feature", "allow": ["shared"] },
{ "from": "shared", "allow": ["shared"] }
]
}]
}
}機能ごとの公開API
各機能はfeatures/auth/index.tsを通じて公開APIを提供します。他のコードは深いパスではなく、'@/features/auth'からインポートします。これにより、利用側を壊さずに内部実装をリファクタリングできます。
// features/auth/index.ts
export { LoginForm } from './LoginForm';
export { useAuth } from './useAuth';
export type { User, AuthState } from './auth.types';
// Consumers:
import { LoginForm, useAuth } from '@/features/auth';
// NOT: import { LoginForm } from '@/features/auth/LoginForm';サブ機能のネスト
大規模な機能には、dashboard/widgets/やdashboard/charts/のようなサブフォルダーを設けられます。ただし、2~3階層より深くネストするのは避けてください。検索が困難になります。
ルートを配置する場所
ページやルートは、最上位のpages/またはroutes/フォルダーに配置できます。これらは薄い層にし、機能からコンポーネントとフックを取得して組み合わせます。
src/
pages/
Dashboard.page.tsx // composes Dashboard widgets from features/dashboard/
Cart.page.tsx // composes from features/cart/
features/
shared/既存アプリを移行する
まずは新しい機能だけから始め、新しいコードをfeatures/に配置します。一度にすべてをリファクタリングしないでください。古いファイルを変更する機会に、少しずつ移動します。ESLintの境界ルールによって、新しい構成への逆戻りを防げます。
種類別構成が適している場合
非常に小規模なアプリ(コンポーネントが30個未満)やライブラリでは、種類別の構成で問題ありません。auth、checkout、billing、settingsなど、明確なビジネスドメインができたら、すぐに機能別の構成を使用してください。
クイックチェック
ファイルの種類ではなく機能別にコードをまとめる主な整理上のメリットは何ですか?
振り返り:機能別の構成
features/にはドメイン固有のコードを、shared/には機能をまたいで使用するユーティリティを配置します。各機能は公開用のindex.tsを提供します。機能同士はインポートせず、shared/からのみインポートします。eslint-plugin-boundariesでこのルールを強制します。ページやルートは機能を組み合わせます。移行は段階的に行います。小規模なアプリでは種類別の構成で問題ありません。
よくある質問
「機能ベースのフォルダー構成」レッスンは無料ですか?
はい。「機能ベースのフォルダー構成」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Frontend Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Frontend Academyコースには全4レッスンが含まれています。
「機能ベースのフォルダー構成」で何を学びますか?
型ではなく機能ドメイン単位でコードを整理し、テスト、スタイル、コンポーネントを近くに配置して、eslint-plugin-boundariesで境界を強制します。 ブラウザで直接実行するハンズオンコードでFrontend Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
Frontend Academyを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのFrontend Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン4/4です。
「機能ベースのフォルダー構成」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このFrontend Academyレッスンでコードを書いて実行できますか?
はい。すべてのFrontend Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。
このコースのすべてのレッスン
- Atomic Design:Atoms・Molecules・Organisms
- TurborepoによるMonorepo構成
- マイクロフロントエンド:Module Federation
- 機能ベースのフォルダー構成