【ITニュース解説】Let’s Learn Feature-Sliced Design (FSD)
2025年09月28日に「Dev.to」が公開したITニュース「Let’s Learn Feature-Sliced Design (FSD)」について初心者にもわかりやすく解説しています。
ITニュース概要
Feature-Sliced Design (FSD)は、フロントエンドのコードを機能ごとに整理する設計手法だ。ファイル配置の混乱を解消し、コードの役割に応じて層や領域、区分に明確に分ける。依存関係を厳しく管理することで、大規模開発での整合性を保ち、再利用性やAIとの協調性を高める。
ITニュース解説
システム開発において、特にアプリケーションの規模が大きくなると、多数のファイルやコードが複雑に絡み合い、管理が非常に難しくなるという課題に直面することがある。多くの開発者が協力して一つのプロジェクトを進める際、どのコードをどこに配置すべきか、あるいは特定のコードを変更した際に他の部分に意図しない影響が出ないか、といった問題は避けて通れない。このような状況は「このファイルをどこに置けばいいのか?」という混乱を引き起こし、開発効率を著しく低下させる可能性がある。この混沌とした状態を解決し、コードベースを秩序だったものにするための設計手法の一つが「Feature-Sliced Design(FSD)」である。FSDは主にフロントエンド開発のために提唱されたアーキテクチャだが、その本質的な考え方はシステム全体の設計においても非常に有用である。
FSDの根本的な目的は、アプリケーションのコードを「機能」単位で明確に分割し、コード間の依存関係を厳格に制御することにある。これにより、いわゆる「スパゲッティコード」と呼ばれる、整理されておらず複雑に絡み合った状態を防ぐことができる。これまでの開発では、「components/」という共通コンポーネントをまとめるフォルダや、「utils/」という汎用関数を集めるフォルダなどが乱立し、結果としてどこに何があるのか分かりにくくなる問題が頻繁に発生していた。FSDは、このような「フォルダの地獄」から脱却し、より構造的で保守しやすい開発環境を実現する。
近年、AIがコードを生成する能力が向上する中で、人間が果たすべき最も価値のある役割は「設計」だと言われている。AIが生成するコードは、その粒度が多岐にわたるため、柔軟かつ堅牢な設計がなければ、人間とAIの協調作業がスムーズに進まない可能性がある。FSDは、コードの明確な配置場所、すなわち「棚」のような構造を定義することで、AIと人間がお互いの作業を邪魔することなく、効率的に開発を進めるための強固な基盤を提供する。
FSDは、主に三つの中心的な概念に基づいて構築される。一つ目は「Layer(層)」、二つ目は「Slice(スライス)」、そして三つ目は「Segment(セグメント)」である。これらの概念はそれぞれ、コードの整理と依存関係の管理において異なる役割を担う。
まず「Layer(層)」は、アプリケーション全体をその責任の範囲に基づいて分割する「棚」のような役割を果たす。FSDでは、アプリケーションのコードを以下の六つの主要な層に分割する。 「app/」層は、アプリケーションのエントリポイントであり、ルーティングの設定、テーマの適用、国際化対応、フレームワークレベルの初期設定など、アプリケーション全体の基盤となる構成要素を管理する。 「pages/」層は、URLと連動するページレベルのUIを配置する場所である。各ページに特有のレイアウトや、そのページ専用のUIコンポーネントがここに含まれる。 「widgets/」層は、複数のUIコンポーネントを組み合わせて特定のユースケースに対応するUIの複合体を配置する。例えば、複数の要素から構成されるカード、テーブル、フォームなどの部品が該当する。 「features/」層は、ユーザー認証、検索クエリの構築、ショッピングカートへのアイテム追加など、アプリケーションが提供する具体的な機能の振る舞いを実装する。これはユーザーがアプリケーションとどのように相互作用するかを定義する核心的な部分である。 「entities/」層は、ユーザー、商品、注文といったビジネスドメインにおける「もの」や「概念」を定義する。これらのデータ構造や関連するロジックがここに含まれる。 「shared/」層は、アプリケーション全体で共通して利用される部品や機能を配置する。これには、汎用的なUIコンポーネント、カスタムフック、ユーティリティ関数、型定義など、あらゆる層から参照される可能性のある共通的な要素が集められる。
これらの層の間には厳格な「依存関係のルール」が適用される。このルールは「上位の層は下位の層のコードを利用できるが、下位の層は上位の層のコードを利用できない」という一方通行の原則である。例えば、「app/」層は全ての層のコードを利用できるが、「entities/」層は「shared/」層のコードしか利用できない。この原則を遵守することで、コードが予測不能な方向で繋がり合い、変更が予期せぬ場所へ影響を及ぼす「スパゲッティ状態」が効果的に防止され、開発の安定性が保たれる。
次に「Slice(スライス)」は、各Layerの内部をさらにビジネスドメイン(特定の機能や概念)ごとに分割する「引き出し」のような役割を果たす。例えば、「pages/」層の中には「user-profile/」や「order-history/」といった個別のスライスが存在し、「features/」層には「user-login/」や「search-query/」のようなスライスが存在する。各スライスは原則として独立性を保ち、他のスライスの内部実装に直接アクセスすることは許可されない。しかし、必要に応じて@xのような特別な仕組みを利用して、公開APIを介してのみコードを安全に共有することも可能である。これにより、機能ごとの独立性が維持され、ある機能の変更が他の機能に不必要な影響を与えるリスクが低減される。
最後に「Segment(セグメント)」は、Sliceの内部をさらに目的別に分割する「仕切り」である。一般的なセグメントには、「ui/」(コンポーネント、スタイルなど表示に関するもの)、「api/」(API呼び出し、型定義など通信に関するもの)、「model/」(ストア、スキーマ、ビジネスロジックなどデータや状態管理に関するもの)、「lib/」(ヘルパー関数、ユーティリティなど)、「config/」(定数、フラグなど設定に関するもの)といったものが含まれる。この細分化により、表示ロジックとビジネスロジックが明確に分離され、コードの役割と責任がより一層明確になる。
FSDを採用することには、多くの具体的なメリットがある。まず「一貫性」が高まるという点である。全ての開発者が同じフォルダ構造とルールに従うため、新しい開発者でもプロジェクトのコードベースに容易に順応でき、学習コストが低減される。次に「安定性」が向上する。スライスによって機能が適切に隔離されるため、ある機能の変更が他の部分に意図しない副作用を引き起こすリスクが減少し、コードの変更に対する不安が軽減される。また「再利用性」も大きな利点である。「shared/」層、「entities/」層、そして「features/」層には、アプリケーション全体で再利用可能な部品が集められるため、必要なコードを容易に見つけ出し、効率的に再利用できる。これは、AIがコードを生成する際にも、既存の構造を尊重しやすくなるという点で特に重要である。さらに「柔軟性」もFSDの強みである。新しい要件や機能が追加された場合でも、「どこに新しくコードを追加すればよいか」が明確なため、迷うことなくアプリケーションを拡張できる。そして現代において欠かせないのが「AIフレンドリー」であるという点である。FSDのように明確なルールに基づいた設計は、AIが構造を理解しやすく、AIが生成したコードもこの構造に沿って配置されるため、人間とAIの協調作業がスムーズに進む。
FSDを効果的に導入するためのいくつかのヒントも存在する。「entities/」層には「ユーザー」「商品」「カート」といった「名詞」にあたるドメインモデルを配置し、「features/」層には「ログイン」「カートに追加」「検索フォーム」といった「動詞」にあたる機能的な振る舞いを配置するという区別を意識すると、コードの分類が容易になる。また、スライス間でコードを安全に共有する際には、@xのような特別な仕組みを利用して公開API経由でのみアクセスを許可することで、内部構造への不用意な依存を防ぐことができる。UIコンポーネントの設計においては、「Atomic Design」のような手法を「ui/」セグメント内で活用することも可能である。さらに、ESLintのようなコード品質チェックツールにeslint-plugin-boundariesといったプラグインを導入することで、FSDのレイヤー間の依存関係ルールを自動的にチェックし、違反を未然に防ぐことが可能になる。
AIがコードを生成する時代において、人間が設計した構造に沿ってAIがコードを生成することで、コードレビューのコストを削減し、人間とAIの間の摩擦を減らすことが可能となる。FSDは、このように明確な「家」をAIが書いたコードに与えることで、開発プロセス全体の効率を向上させる役割を果たす。
FSDは、「Layer(棚):依存関係を制御し、無秩序なインポートを防ぐ役割」、「Slice(引き出し):ビジネスドメインごとにコードを整理し、機能の居住地を明確にする役割」、「Segment(仕切り):スライス内でUI、API、モデルなどの目的別に分割する役割」という三つの要素で構成されている。この設計思想を理解し実践することは、複雑化する現代のシステム開発において、混沌としたコードベースを整理し、将来にわたる拡張性と保守性を確保するための重要なスキルとなる。