メインコンテンツにスキップ

レイヤー

レイヤー(層)は、Feature-Sliced Designにおける組織階層の最初のレベルです。その目的は、コードを必要な責任の量とアプリケーション内の他のモジュールへの依存度に基づいて分割することです。

注記

このページでのモジュールは、アプリケーション内のファイルやインデックスファイルを持つディレクトリを指している。npmパッケージと混同しないでください。

各レイヤーは、コード内のモジュールにどれだけの責任を割り当てるべきかを判断するのに役立つ特別な意味を持っています。レイヤー名とレイヤーの意味は、Feature-Sliced Designを使用して構築されたすべてのプロジェクトで標準化されています。

合計で7つのレイヤーがあり、最も責任と依存度が高いものから最も低いものへと配置されています。

ファイルシステムのツリーは、1つのルートフォルダsrcと7つのサブフォルダ(app、processes、pages、widgets、features、entities、shared)で構成されています。processesフォルダは少し薄く表示されています。 ファイルシステムのツリーは、1つのルートフォルダsrcと7つのサブフォルダ(app、processes、pages、widgets、features、entities、shared)で構成されています。processesフォルダは少し薄く表示されています。
  1. App (アップ)
  2. Processes (プロセス、非推奨)
  3. Pages (ページ)
  4. Widgets (ウィジェット)
  5. Features (フィーチャー)
  6. Entities (エンティティ)
  7. Shared (シェアード)

プロジェクトで全てのレイヤーを使用する必要はないので、プロジェクトに価値をもたらすレイヤーだけを追加してください。

レイヤーのインポートルール

レイヤーは、強く結合されたモジュールのグループであるスライスから構成されています。Feature-Sliced Designは低い結合度をサポートしているため、スライス間の依存関係はレイヤーのインポートルールによって制御されます。

スライス内のモジュールは、下層のレイヤーにあるスライスのみをインポートできる。

例えば、~/features/aaa では、スライスは aaa であるため、~/features/aaa/api/request.ts ファイルは ~/features/bbb フォルダー内のモジュールからコードをインポートすることはできませんが、~/entities~/shared から、また ~/features/aaa 内の隣接モジュールからはインポートできます。

レイヤーの定義

Shared層

Shared層は、プロジェクトやビジネスの特性から切り離された、孤立したモジュール、コンポーネント、抽象化のことです。

このレイヤーは他のレイヤーとは異なり、スライスではなく直接セグメントで構成されています。

内容の例

  • UIライブラリ
  • APIクライアント
  • ブラウザAPIと連携するコード

Entities層

Entities層は、プロジェクトの本質を形成する現実世界の概念です。通常、これはビジネスがプロダクトを説明するために使用する用語です。

このレイヤーの各スライスは、ユーザーインターフェースの静的要素、データストレージ、およびCRUD(作成・読み取り・更新・削除)操作を含みます。

スライスの例

SNS Gitフロントエンド(例:GitHub)
  • ユーザー
  • 投稿
  • グループ
  • リポジトリ
  • ファイル
  • コミット
ヒント

Gitフロントエンドの例では、リポジトリファイルを含むことに気付くかもしれません。これは、リポジトリが他のエンティティを内包する高レベルのエンティティであることを示しています。このような高レベルのエンティティを作成ことは一般的が、この場合、レイヤーのインポートルールを破らないことは時に難しいです。

この問題を解決するためのいくつかの提案があります。

  • エンティティのUIは、下位レベルのエンティティを挿入するためのスロットを含むべき
  • エンティティ間の相互作用に関連するビジネスロジックは、通常、Features層に配置されるべき
  • データベースのエンティティインターフェースは、APIクライアントの近くにあるShared層に抽出できる

Features層

Features層は、ユーザーがアプリケーション内でビジネスエンティティとインタラクションするために行うアクションで、価値のある結果を達成するためのものです。ここには、ユーザーのためにアプリケーションが実行するアクションも含まれています。

このレイヤーのスライスは、価値を生み出すアクションを実行するためのインタラクティブなUI要素、内部状態、およびAPIリクエストを含むことができます。

スライスの例

SNS Gitフロントエンド(例:GitHub) ユーザーの代わりに行うアクション
  • ログイン
  • 投稿を作成
  • グループに参加
  • ファイルを変更
  • コメントを残す
  • ブランチをマージ
  • ダークテーマを自動的に有効にする
  • バックグラウンドで計算を実行する
  • User-Agentに基づくアクション

Widgets層

Widgets層は、独立したUIブロックであり、エンティティやフィーチャーなどの低レベルユニットの組み合わせです。

このレイヤーは、エンティティのインターフェースに残されたスロットを、他のフィーチャーからのインタラクティブ要素やエンティティで埋めることを可能にしています。したがって、通常、このレイヤーにはビジネスロジックは配置されず、代わりにフィーチャーに保存されます。このレイヤーの各スライスは、使用可能なUIコンポーネントを含み、時にはビジネスロジック以外のロジック(例えば、ジェスチャー、キーボードとの相互作用など)を含むことがあります。

時には、このレイヤーにビジネスロジックを配置する方が便利な場合もあります。これは、ウィジェットがかなりのインタラクティブ性を持っている場合(例えば、インタラクティブテーブル)で、その中のビジネスロジックが再利用されない場合によく発生します。

スライスの例

SNS Gitフロントエンド(例:GitHub)
  • 投稿カード
  • ユーザープロフィールのヘッダー(アクション付き)
  • リポジトリ内のファイル一覧(アクション付き)
  • スレッド内のコメント
  • リポジトリカード
ヒント

ネストされたルーティングシステム(例えば、Remixルーター)を使用している場合、Widgets層をPages層と同様に使用することが便利なケースがあります。例えば、バックエンドからのデータを取得し、読み込み状態やエラー処理を含むインターフェースブロックを作成する際に役立てます。また、Pages層のレイアウトをここに配置することもできます。

Pages層

Pages層は、ページベースのアプリケーション(例えば、ウェブサイト)のページや、画面ベースのアプリケーション(例えば、モバイルアプリ)の画面やアクティビティです。

このレイヤーは、その構成的な性質においてWidgets層に似ていますが、より大きな規模で構成されています。Pages層の各スライスは、ルーターに接続できるUIコンポーネントを含むほか、データ取得やエラー処理のロジックを含むこともできます。

スライスの例

SNS Gitフロントエンド(例:GitHub)
  • ニュースフィード
  • コミュニティページ
  • 公開ユーザープロフィール
  • リポジトリページ
  • ユーザーのリポジトリ
  • リポジトリ内のブランチ

Processes層

注意

このレイヤーは、廃止されています。現在の仕様バージョンでは、これを避け、内容を features層 と app層 に移動することを推奨しています。

Processes層は、複雑なマルチページインタラクションが必要な際に使用されます。

このレイヤーは意図的にあまり定義されていません。ほとんどのアプリケーションにはこのレイヤーは必要ありません。ルーターやサーバーレベルのロジックはApp層に残すべきです。このレイヤーは、App層が成長しすぎて管理できなくなった場合にのみ使用を検討してください。

App層

App層は、アプリ全体に関するすべてのことです。技術的な意味(例えば、コンテキストプロバイダー)とビジネス的な意味(例えば、分析)を含みます。

このレイヤーは通常、Shared層と同様にスライスを含まず、直接セグメントで構成されています。

内容の例

  • スタイル
  • ルーター
  • データストレージやその他のコンテキストプロバイダー
  • 分析の初期化