FSD(Feature-Sliced Design)とは、フロントエンド開発における複雑性を解消するために考案された、機能中心のアーキテクチャ設計手法である。
プロジェクトを「レイヤー」「スライス」「セグメント」という3つの階層に分割し、依存関係を一方通行に制御することで、保守性と拡張性を最大化する。
FSDのアーキテクチャ
FSDの最大の特徴は、コードを単なる「機能ごと」に分けるのではなく、その役割の重み(階層)に応じて厳格に分類する点にある。
- 階層構造(Layers)による責務の分離
FSDは、app, processes (非推奨になりつつある), pages, widgets, features, entities, shared という7つの標準的なレイヤーで構成される。下位のレイヤー(sharedやentities)は、上位のレイヤー(pagesやwidgets)を知ることはできない。この「上から下への一方通行」というルールが、スパゲッティコードの発生を物理的に阻止する壁となる。
- スライス(Slices)によるドメイン分割
各レイヤー内(sharedを除外)では、特定のビジネスドメインごとに「スライス」を作成する。例えば entities/user や features/auth-by-email といった具合だ。スライス間での直接的なインポートは禁止されており、これにより「ある機能を修正したら、全く関係のない画面が壊れた」という副作用を最小限に抑え込める。
- セグメント(Segments)による実装コードの整理
スライスの内部は、さらに ui, model, api, lib といったセグメントに細分化される。UIコンポーネント、状態管理ロジック、データ取得処理が混ざることなく整理されるため、コードの所在が明確になり、エンジニアが迷子になる時間を削り取ることができる。
FSDのメリット
FSDを採用することで、フロントエンド開発が抱える「成長に伴うカオス化」という宿命から解放される。
- 認知負荷の劇的な低減
開発者が新しい機能を追加したり、既存のバグを追跡したりする際、探すべき場所がアーキテクチャの定義から自動的に決まる。巨大な components フォルダの中から目当てのファイルを探す苦行は消え去り、脳のエネルギーを純粋なロジックの実装に集中させることが可能になる。
- 依存関係の可視化と制御
「どのモジュールがどこに依存しているか」がディレクトリ構造そのものに反映されるため、不用意な結合が即座に浮き彫りになる。循環参照の発生を未然に防ぎ、特定の機能だけを切り出してテストしたり、別のプロジェクトへ移植したりする作業が驚くほどスムーズに進む。
- チーム開発における衝突の回避
機能ごとに独立したディレクトリ(スライス)で作業が完結するため、複数のエンジニアが同じファイルを同時に編集してコンフリクトを起こすリスクが下がる。各々が自分の担当領域に閉じこもって開発を進められるため、デリバリーの速度が格段に向上する。
FSDのデメリット
一方で、FSDは「銀の弾丸」ではない。その厳格さゆえに、導入には相応のコストと覚悟が求められる。
- 初期学習コストの高さと厳格な規律
FSDの概念は抽象的であり、特に「これは feature なのか、それとも entity なのか」という判断に最初は誰もが頭を抱える。チーム全員がこの設計思想を深く理解し、コードレビューで逸脱を厳しくチェックし続ける根気が必要だ。理解が中途半端なまま進めると、かえって複雑怪奇な構造を生む結果となりかねない。
- ファイル数とディレクトリ階層の増大
小さなコンポーネント一つを作るのにも、複数のフォルダと index ファイルを用意しなければならない。ファイルシステムが肥大化しやすく、小規模なプロジェクトやプロトタイプ開発においては、オーバースペックに感じられる場面も少なくない。いわゆる「ボイラープレート」の多さに辟易する開発者もいるだろう。
- 既存プロジェクトへの導入の難易度
すでに別の設計思想(あるいは無秩序な状態)で動いている大規模なプロダクトをFSDへ移行するのは、まさに心臓移植のような困難を伴う。一気に変えようとすれば開発が止まるため、少しずつ領域を切り出していく粘り強いリファクタリングの体制が不可欠となる。
FSDの実装方法
FSDを実際にプロジェクトへ落とし込む際は、まずディレクトリ構造の雛形を固めることから始める。
- Public API(index.ts)の徹底
各スライスやセグメントの直下に index.ts を配置し、外部に公開する資産だけを export する。内部実装の詳細を隠蔽し、外側からはその index.ts だけを参照するように強制することで、モジュール間の疎結合を担保する。これが崩れるとFSDの屋台骨が崩れると言っても過言ではない。
- ESLintによる自動ガードの導入
人間が手動で依存ルールを守り続けるのは限界がある。eslint-plugin-boundaries などのツールを導入し、「上位レイヤーから下位レイヤーへのアクセス禁止」や「スライスを跨いだ直接参照の禁止」を機械的に検証する。CI/CDのプロセスに組み込むことで、アーキテクチャの劣化を自動的に食い止める仕組みを構築すべきだ。
- スライスの粒度の見極め
最初は entities (データ構造の定義)と features (ユーザーの行動に伴う処理)の境界線に迷うだろう。例えば「記事」という概念は entities/article だが、「記事を編集するボタンと挙動」は features/article-edit となる。このように、ビジネス価値に直結する「動き」を feature として切り出す感覚をチームで養うことが、実装を成功させる鍵となる。
まとめ
FSDは、フロントエンドが単なる「見た目」の調整役から、複雑なビジネスロジックを抱える「アプリケーション」へと進化した現代において、非常に強力な武器となる設計手法だ。階層化とドメイン分割を徹底することで、コードの寿命を延ばし、変更に強いプロダクトへと育て上げることができる。
もちろん、ディレクトリが深くなることや学習の壁といった負の側面もある。しかし、数万行、数十万行と膨れ上がるソースコードを前にして立ち往生する未来を考えれば、FSDが提供する「秩序」という見返りは、支払うコストを十分に上回るはずだだ。
プロジェクトの規模やチームの習熟度を見極めた上で、まずは shared や entities といった基礎部分から、この洗練された設計思想を取り入れてみてはどうだろうか。
