Skip to content

Commit

Permalink
feat: add strict definitions for layers (feature-sliced#547)
Browse files Browse the repository at this point in the history
  • Loading branch information
illright authored Apr 22, 2023
1 parent 07845d9 commit 23e960d
Show file tree
Hide file tree
Showing 57 changed files with 630 additions and 2,845 deletions.
25 changes: 10 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
![feature-sliced-banner](/static/img/banner.jpg)

<!-- ⚡ Add primary information & features about your repository -->
**Feature-Sliced Design** (FSD) is an architectural design methodology for *frontend applications*. It aims to [**divide an application according to business logic and scopes of responsibility**][refs-splitting]
**Feature-Sliced Design** (FSD) is an architectural design methodology for *frontend applications*. It aims to **divide an application according to business logic and scopes of responsibility**

- Provides [**explicitness, controllability and adaptability**][refs-arch-req] of architecture
- Based on [**time-tested**][refs-motivation-why] design practices and concepts
Expand Down Expand Up @@ -52,13 +52,13 @@ And therefore, instead of inventing and documenting it every time, it is better

The methodology is designed to **simplify and standardize the decomposition of logic for large and long-lived projects.**

To do this, it introduces a number of [concepts][refs-concepts] and [abstractions][refs-splitting], on which the architecture *can be based* from project to project - from here we get *a number of advantages*
To do this, it introduces a number of [concepts][refs-concepts] and abstractions, on which the architecture *can be based* from project to project - from here we get *a number of advantages*

> **Note:** [Module][refs-module] - the structural unit of the project (file / directory)
> **Note:** Module - the structural unit of the project (file / directory)
### Explicit business logic

Modules are distributed according to [scope of influence, business responsibility and technical purpose][refs-splitting]
Modules are distributed according to scope of influence, business responsibility and technical purpose.

Thanks to this, *the architecture is standardized and becomes easier to read*

Expand All @@ -82,7 +82,7 @@ Thanks to this *it is easy to add and onboard new people to the team, as well as

### Controlled reuse of logic

Each module has its own limitations and recommendations for reuse according to [its layer][refs-splitting-layers]
Each module has its own limitations and recommendations for reuse according to its layer.

Thanks to this, *a balance is maintained between compliance with the `DRY` principle and the ability to customize the module logic without overhead overrides*

Expand All @@ -106,13 +106,13 @@ The module should not **depend directly** on other modules of the same layer or

Orientation **to the needs of the business and the user**

- Also includes splitting the structure by business domains *(so-called ["slices"][refs-splitting-slices])*
- Also includes splitting the structure by business domains *(so-called "slices")*

## Abstractions

For [architecture design][refs-splitting] the methodology suggests operating with [familiar abstractions][refs-adaptability], but in a more consistent and consistent order.
For architecture design the methodology suggests operating with [familiar abstractions][refs-adaptability], but in a more consistent and consistent order.

### [`Layers`][refs-splitting-layers]
### `Layers`

The first level of abstraction is **according to the scope of influence**

Expand All @@ -123,13 +123,13 @@ The first level of abstraction is **according to the scope of influence**
- `entities` - business entities *(viewer, order, ...)*
- `shared` - reused infrastructure code *(UIKit, libs, API, ...)*

### [`Slices`][refs-splitting-slices]
### `Slices`

The second level of abstraction is **according to the business domain**

The rules by which the code is divided into slices *depend on the specific project and its business rules* and are not determined by the methodology

### [`Segments`][refs-splitting-segments]
### `Segments`

The third level of abstraction is **according to the purpose in the implementation**

Expand Down Expand Up @@ -244,12 +244,7 @@ If there are variations, how best to place indents-welcome:)
[refs-isolation]: https://feature-sliced.design/docs/reference/isolation
[refs-needs-driven]: https://feature-sliced.design/docs/about/understanding/needs-driven

[refs-module]: https://feature-sliced.design/docs/reference/units#module
[refs-knowledge]: https://feature-sliced.design/docs/about/understanding/knowledge-types
[refs-splitting]: https://feature-sliced.design/docs/reference/units/decomposition
[refs-splitting-layers]: https://feature-sliced.design/docs/reference/units/decomposition#group-layers
[refs-splitting-slices]: https://feature-sliced.design/docs/reference/units/decomposition#group-slices
[refs-splitting-segments]: https://feature-sliced.design/docs/reference/units/decomposition#group-segments

[refs-migration-v1]: https://feature-sliced.design/docs/guides/migration/from-v1

Expand Down
29 changes: 0 additions & 29 deletions config/docusaurus/routes.js
Original file line number Diff line number Diff line change
Expand Up @@ -114,35 +114,6 @@ const LEGACY_ROUTES = [
from: "/docs/concepts/cross-communication",
to: "/docs/reference/isolation",
},
{
title: "App splitting",
from: "/docs/concepts/app-splitting",
to: "/docs/reference/units/decomposition",
},
{
title: "Glossary",
from: "/docs/reference/glossary",
to: "/docs/reference/units",
},
{
title: "Segments",
from: "/docs/reference/segments",
to: "/docs/reference/units/segments",
},
{
title: "Layers",
from: [
"/docs/reference/layers/overview",
"/docs/reference/layers/app",
"/docs/reference/layers/processes",
"/docs/reference/layers/pages",
"/docs/reference/layers/widgets",
"/docs/reference/layers/features",
"/docs/reference/layers/entities",
"/docs/reference/layers/shared",
],
to: "/docs/reference/units/layers",
},
],
},
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ Answered [here](/docs/guides/migration/from-v1)

### Can I embed pages/features/entities into each other?

Answered [here](/docs/reference/units/decomposition#group-slices)
Answered [here](/docs/reference/slices-segments#slices)

### How do I work with the authorization context?

Expand All @@ -73,7 +73,7 @@ At the same time, Atomic Design [is well applied](https://t.me/feature_sliced/16
- `Feature` - business feature, **action on an entity**
- create-blog-post / login-by-oauth / edit-account / publish-video / ...

See also [comparison reference](/docs/reference/units/layers), [viewer implementation of logic by layers](/docs/guides/examples/auth)
See also [comparison reference](/docs/reference/layers), [viewer implementation of logic by layers](/docs/guides/examples/auth)

### Where to store the layout/template of pages?

Expand All @@ -94,7 +94,7 @@ It will be, at the moment - in development =)
### Can I store the features used on one page directly in the page directory?

The methodology strongly recommends against doing this, since [each module has a corresponding place in the structure](/docs/reference/units/decomposition)
The methodology strongly recommends against doing this, since each module has a corresponding place in the structure.

Otherwise , there is a risk of complicating the project's code base

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,11 @@ If you have an existing project, fear not — FSD can be adopted incrementally.

## Basics

In FSD, a [project consists][refs-splitting] of <mark>layers</mark>, each layer is made up of <mark>slices</mark> and each slice is made up of <mark>segments</mark>.
In FSD, a project consists of <mark>layers</mark>, each layer is made up of <mark>slices</mark> and each slice is made up of <mark>segments</mark>.

![themed--scheme](/img/visual_schema.jpg)

The **layers** are standardized across all projects and vertically arranged. Modules on one layer can only interact with modules from the layers strictly below. There are currently seven of them (bottom to top):
The **layers** are standardized across all projects and vertically arranged. Modules on one layer can only interact with modules from the layers strictly below. There are currently six of them (bottom to top):

1. `shared` — reusable functionality, detached from the specifics of the project/business.
<small>(e.g. UIKit, libs, API)</small>
Expand All @@ -35,9 +35,7 @@ The **layers** are standardized across all projects and vertically arranged. Mod
4. `widgets` — compositional layer to combine entities and features into meaningful blocks.
<small>(e.g. IssuesList, UserProfile)</small>
5. `pages` — compositional layer to construct full pages from entities, features and widgets.
6. `processes` — complex inter-page scenarios.
<small>(e.g., authentication)</small>
7. `app` — app-wide settings, styles and providers.
6. `app` — app-wide settings, styles and providers.


Then there are **slices**, which partition the code by business domain. This makes your codebase easy to navigate by keeping logically related modules close together. Slices cannot use other slices on the same layer, and that helps with high cohesion and low coupling.
Expand All @@ -55,7 +53,6 @@ In most cases, [it is recommended][ext-disc-api] to place `api` and `config` onl
Let's consider a social network application.

* `app/` contains setup of routing, store and global styles.
* `processes/` contains the part of authentication that is responsible for reading/writing authentication tokens.
* `pages/` contains the route components for each page in the app, mostly composition, hardly any logic.

Within that application, let's consider a post card in a news feed.
Expand Down Expand Up @@ -99,4 +96,3 @@ It's advised to refrain from adding new large entities while refactoring or refa
[ext-disc-api]: https://github.com/feature-sliced/documentation/discussions/66
[refs-examples]: /examples
[refs-migration]: /docs/guides/migration
[refs-splitting]: /docs/reference/units/decomposition
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ Here's how it will help us in the future

#### Layers: app

As you can see , we have moved all the basic logic to the [`app/`][refs-app] directory
As you can see , we have moved all the basic logic to the `app/` directory

It is there, according to the methodology, that all the preparatory logic should be placed:

Expand Down Expand Up @@ -288,8 +288,8 @@ const App = () => (

Here we used several layers at once:

- [`app`][refs-app] - to initialize the router *(HOC: withRouter)*
- [`pages`][refs-pages] - for storing page modules
- `app` - to initialize the router *(HOC: withRouter)*
- `pages` - for storing page modules

### 1.5 Let's connect UIKit

Expand Down Expand Up @@ -332,7 +332,7 @@ To do this, we decompose our functionality *by responsibility scopes [(layers)][

> **Note:** the diagram shows *an experimental layer of "Widgets"*, which is unnecessary in the framework of the tutorial and the specification of which will be added soon
#### [Pages][refs-pages]
#### Pages

We will outline the basic necessary pages, and user expectations from them:

Expand Down Expand Up @@ -371,27 +371,27 @@ This is due to the usual conditions of the project development:

Even with the basic partitioning, we see that:

- there are common [entities][refs-entities] between the pages and their display *(Task)*
- there are common [features][refs-features] *between the pages (Mark the task completed / unfulfilled)*
- there are common entities between the pages and their display *(Task)*
- there are common features *between the pages (Mark the task completed / unfulfilled)*

Accordingly, it seems logical to continue to decompose the task, but already based on the above-mentioned features for the user.

#### [Features][refs-features]
#### Features

Parts of functionality that bring value to the user

- `<ToggleTask />` - (component) Mark a task as completed / unfulfilled
- `<TasksFilters/>` - (component) Set filtering for the task list

#### [Entities][refs-entities]
#### Entities

Business entities on which a higher-level logic will be built

- `<TaskCard />` - (component) Task card, with information display
- `getTasksListFx({ filters })` - (effect) Loading the task list with parameters
- `getTaskByIdFx(taskId: number)`- (effect) Uploading a task by ID

#### [Shared][refs-shared]
#### Shared

Reused shared modules, without binding to the domain scopes

Expand Down Expand Up @@ -817,24 +817,17 @@ Below in [Codesandbox][ext-sandbox] is an example of the resulting TodoApp, wher
- [(Overview) How to Organize Your React + Redux Codebase][ext-pluralsight]
- Analysis of several approaches to structuring React projects
- [Guides and examples of the methodology application (+ Migration from v1)][refs-guides]
- [About splitting the application][refs-splitting]
- [Reference material on the methodology][refs-reference]

[refs-motivation]: /docs/about/motivation

[refs-needs]: /docs/about/understanding/needs-driven
[refs-public-api]: /docs/reference/public-api
[refs-splitting]: /docs/reference/units/decomposition

[refs-low-coupling]: /docs/reference/isolation/coupling-cohesion
[refs-guides]: /docs/guides
[refs-reference]: /docs/reference
[refs-layers]: /docs/reference/units/layers
[refs-app]: /docs/reference/units/layers/app
[refs-pages]: /docs/reference/units/layers/pages
[refs-features]: /docs/reference/units/layers/features
[refs-entities]: /docs/reference/units/layers/entities
[refs-shared]: /docs/reference/units/layers/shared
[refs-layers]: /docs/reference/layers

[ext-pluralsight]: https://www.pluralsight.com/guides/how-to-organize-your-react-+-redux-codebase
[ext-pluralsight--flat]: https://www.pluralsight.com/guides/how-to-organize-your-react-+-redux-codebase#module-theflatstructure
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,6 @@ import WIP from '@site/src/shared/ui/wip/tmpl.mdx'

## Header

> See [examples with widgets](/docs/reference/units/layers/widgets#application-header)
> https://t.me/feature_sliced/2978
## Sidebar
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ In v2 **, other new abstractions** have been added to eliminate the problems of

### `BREAKING` Abstractions & Naming

Now [specific abstractions][refs-abstractions] and [clear recommendations for naming them][refs-adaptability]are defined
Now specific abstractions and [clear recommendations for naming them][refs-adaptability]are defined

[disc-process]: https://github.com/feature-sliced/documentation/discussions/20
[disc-features]: https://github.com/feature-sliced/documentation/discussions/23
Expand All @@ -116,7 +116,7 @@ Now [specific abstractions][refs-abstractions] and [clear recommendations for na
[disc-model]: https://github.com/feature-sliced/documentation/discussions/31#discussioncomment-472645
[disc-api]: https://github.com/feature-sliced/documentation/discussions/66

#### [Layers][refs-abstractions-layers]
#### Layers

- `/app`**application initialization layer**
- *Previous versions: `app`, `core`,`init`, `src/index` (and this happens)*
Expand All @@ -131,7 +131,7 @@ Now [specific abstractions][refs-abstractions] and [clear recommendations for na
- `/shared`[**layer of reused infrastructure code**][disc-shared] 🔥
- *Previous versions: `shared`, `common`, `lib`*

#### [Segments][refs-abstractions-segments]
#### Segments

- `/ui`[**UI segment**][disc-ui] 🔥
- *Previous versions: `ui`, `components`, `view`*
Expand Down Expand Up @@ -160,9 +160,6 @@ Now it is much easier to [observe the principle of low coupling][refs-low-coupli

[refs-low-coupling]: /docs/reference/isolation/coupling-cohesion
[refs-adaptability]: /docs/about/understanding/naming
[refs-abstractions]: /docs/reference/units/decomposition
[refs-abstractions-layers]: /docs/reference/units/decomposition#group-layers
[refs-abstractions-segments]: /docs/reference/units/decomposition#group-segments

[ext-v1]: https://featureslices.dev/v1.0.html
[ext-tg-spb]: https://t.me/feature_slices
Expand Down
29 changes: 14 additions & 15 deletions i18n/en/docusaurus-plugin-content-docs/current/reference/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -4,33 +4,32 @@ hide_table_of_contents: true
pagination_prev: guides/index
---

# 📚 Reference
import NavCard from "@site/src/shared/ui/nav-card/tmpl.mdx"
import { ApiOutlined, GroupOutlined, AppstoreOutlined, NodeIndexOutlined } from "@ant-design/icons";

<span class="badge badge--danger margin-bottom--md">INFORMATION-ORIENTED</span>
# 📚 Reference

<p class="summary">
A detailed description of the methodology's key concepts, that will help you dive deeper into the Feature-Sliced Design philosophy and its application
A detailed description of the key concepts of Feature-Sliced Design.
</p>


## Main

import NavCard from "@site/src/shared/ui/nav-card/tmpl.mdx"
import { ApiOutlined, ApartmentOutlined, PartitionOutlined, NodeIndexOutlined } from "@ant-design/icons";

<NavCard
title="Units"
description="Practices for logical decomposition using layered-sliced structure with extraction of structure units"
to="/docs/reference/units"
Icon={ApartmentOutlined}
tags={['Layers', 'Segments', 'Decomposition']}
title="Layers"
description="Definition of a layer and explanations for all layers"
to="/docs/reference/layers"
Icon={GroupOutlined}
/>
<NavCard
title="Slices and segments"
description="Definitions of a slice and segment, content examples for segments on different layers"
to="/docs/reference/layers"
Icon={AppstoreOutlined}
/>
<NavCard
title="Isolation"
description="Pratices for scalable and efficient module interactions"
to="/docs/reference/isolation"
Icon={NodeIndexOutlined}
tags={['Low Coupling & High Cohesion', 'Decoupling at practice']}
/>
<NavCard
title="Public API"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
label: Isolation
position: 2
Loading

0 comments on commit 23e960d

Please sign in to comment.