You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
**Feature-Sliced Design** (FSD) is an architectural methodology for scaffolding front-end applications. Simply put, it's a compilation of rules and conventions on organizing code. The main purpose of this methodology is to make the project more understandable and stable in the face of ever-changing business requirements.
10
11
@@ -52,7 +53,7 @@ These top-level folders are called _layers_. Let's look deeper:
52
53
53
54
</FileTree>
54
55
55
-
Folders inside `📂 pages` are called _slices_. They divide the layer by domain (in this case, by pages).
56
+
Folders inside `📂 pages` are called _slices_. They divide the layer by domain (in this case, by pages).
56
57
57
58
Folders inside `📂 app`, `📂 shared`, and `📂 pages/article-reader` are called _segments_, and they divide slices (or layers) by technical purpose, i.e. what the code is for.
58
59
@@ -61,7 +62,10 @@ Folders inside `📂 app`, `📂 shared`, and `📂 pages/article-reader` are ca
61
62
Layers, slices, and segments form a hierarchy like this:
62
63
63
64
<figure>
64
-

<p>Pictured above: three pillars, labeled left to right as "Layers", "Slices", and "Segments" respectively.</p>
@@ -112,18 +116,18 @@ Usually these segments are enough for most layers, you would only create your ow
112
116
113
117
## Advantages \{#advantages\}
114
118
115
-
-**Uniformity**
119
+
-**Uniformity**
116
120
Since the structure is standardized, projects become more uniform, which makes onboarding new members easier for the team.
117
121
118
-
-**Stability in face of changes and refactoring**
119
-
A module on one layer cannot use other modules on the same layer, or the layers above.
122
+
-**Stability in face of changes and refactoring**
123
+
A module on one layer cannot use other modules on the same layer, or the layers above.
120
124
This allows you to make isolated modifications without unforeseen consequences to the rest of the app.
121
125
122
-
-**Controlled reuse of logic**
123
-
Depending on the layer, you can make code very reusable or very local.
124
-
This keeps a balance between following the **DRY** principle and practicality.
126
+
-**Controlled reuse of logic**
127
+
Depending on the layer, you can make code very reusable or very local.
128
+
This keeps a balance between following the **DRY** principle and practicality.
125
129
126
-
-**Orientation to business and users needs**
130
+
-**Orientation to business and users needs**
127
131
The app is split into business domains and usage of the business language is encouraged in naming, so that you can do useful product work without fully understanding all other unrelated parts of the project.
Copy file name to clipboardExpand all lines: src/content/docs/docs/get-started/tutorial.mdx
+4-4Lines changed: 4 additions & 4 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -136,7 +136,7 @@ Whatever is inside folders like `pages/feed` or `shared/ui` is only known to tho
136
136
137
137
### Large reused blocks in the UI
138
138
139
-
Earlier we made a note to revisit the header that appears on every page. Rebuilding it from scratch on every page would be impractical, so it’s only natural to want to reuse it. We already have Shared to facilitate code reuse, however, there’s a caveat to putting large blocks of UI in Shared — the Shared layer is not supposed to know about any of the layers above.
139
+
Earlier we made a note to revisit the header that appears on every page. Rebuilding it from scratch on every page would be impractical, so it’s only natural to want to reuse it. We already have Shared to facilitate code reuse, however, there’s a caveat to putting large blocks of UI in Shared — the Shared layer is not supposed to know about any of the layers above.
140
140
141
141
Between Shared and Pages there are three other layers: Entities, Features, and Widgets. Some projects may have something in those layers that they need in a large reusable block, and that means we can’t put that reusable block in Shared, or else it would be importing from upper layers, which is prohibited. That’s where the Widgets layer comes in. It is located above Shared, Entities, and Features, so it can use them all.
142
142
@@ -150,9 +150,9 @@ Let’s also examine a page that’s intended for editing, not reading. For exam
150
150
151
151
It looks trivial, but contains several aspects of application development that we haven’t explored yet — form validation, error states, and data persistence.
152
152
153
-
If we were to build this page, we would grab some inputs and buttons from Shared and put together a form in the `ui` segment of this page. Then, in the `api` segment, we would define a mutation request to create the article on the backend.
153
+
If we were to build this page, we would grab some inputs and buttons from Shared and put together a form in the `ui` segment of this page. Then, in the `api` segment, we would define a mutation request to create the article on the backend.
154
154
155
-
To validate the request before sending, we need a validation schema, and a good place for it is the `model` segment, since it’s the data model. There we will produce error messages and display them using another component in the `ui` segment.
155
+
To validate the request before sending, we need a validation schema, and a good place for it is the `model` segment, since it’s the data model. There we will produce error messages and display them using another component in the `ui` segment.
156
156
157
157
To improve user experience, we could also persist the inputs to prevent accidental data loss. This is also a job of the `model` segment.
158
158
@@ -524,7 +524,7 @@ export function FeedPage() {
524
524
</div>
525
525
</div>
526
526
);
527
-
}
527
+
}
528
528
```
529
529
530
530
Then we need to use the `tag` search parameter in our loader. Change the `loader` function in `pages/feed/api/loader.ts` to the following:
Copy file name to clipboardExpand all lines: src/content/docs/docs/reference/layers.mdx
+8-3Lines changed: 8 additions & 3 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -11,7 +11,12 @@ Layers are the first level of organisational hierarchy in Feature-Sliced Design.
11
11
12
12
There are **7 layers** in total, arranged from most responsibility and dependency to least:
13
13
14
-
<StaticImagepath={['/img/layers/folders-graphic-light.svg', '/img/layers/folders-graphic-dark.svg']}width="180"style={{ float: "right", margin: "0 1em" }}alt="A file system tree, with a single root folder called src and then seven subfolders: app, processes, pages, widgets, features, entities, shared. The processes folder is slightly faded out." />
alt="A file system tree, with a single root folder called src and then seven subfolders: app, processes, pages, widgets, features, entities, shared. The processes folder is slightly faded out."
19
+
/>
15
20
16
21
1. App
17
22
2. Processes (deprecated)
@@ -50,9 +55,9 @@ This layer, like the App layer, _does not contain slices_. Slices are intended t
50
55
Here are the segments that you can typically find in this layer:
51
56
52
57
-`📁 api` — the API client and potentially also functions to make requests to specific backend endpoints.
53
-
-`📁 ui` — the application's UI kit.
58
+
-`📁 ui` — the application's UI kit.
54
59
Components on this layer should not contain business logic, but it's okay for them to be business-themed. For example, you can put the company logo and page layout here. Components with UI logic are also allowed (for example, autocomplete or a search bar).
55
-
-`📁 lib` — a collection of internal libraries.
60
+
-`📁 lib` — a collection of internal libraries.
56
61
This folder should not be treated as helpers or utilities ([read here why these folders often turn into a dump][ext-sova-utility-dump]). Instead, every library in this folder should have one area of focus, for example, dates, colors, text manipulation, etc. That area of focus should be documented in a README file. The developers in your team should know what can and cannot be added to these libraries.
57
62
-`📁 config` — environment variables, global feature flags and other global configuration for your app.
58
63
-`📁 routes` — route constants or patterns for matching routes.
A public API is a _contract_ between a group of modules, like a slice, and the code that uses it. It also acts as a gate, only allowing access to certain objects, and only through that public API.
10
11
@@ -70,8 +71,11 @@ Index files like `index.js`, also known as barrel files, are the most common way
70
71
Circular import is when two or more files import each other in a circle.
71
72
72
73
<figure>
73
-
<imgsrc="../../../../../static/img/circular-import-light.svg"data-theme-only="light"width="60%"alt="Three files importing each other in a circle" />
74
-
<imgsrc="../../../../../static/img/circular-import-dark.svg"data-theme-only="dark"width="60%"alt="Three files importing each other in a circle" />
alt="Three files importing each other in a circle"
78
+
/>
75
79
<figcaption>
76
80
Pictured above: three files, `fileA.js`, `fileB.js`, and `fileC.js`, importing each other in a circle.
77
81
</figcaption>
@@ -147,9 +151,9 @@ Having a large amount of index files in a project can slow down the development
147
151
148
152
There are several things you can do to tackle this issue:
149
153
1. The same advice as in ["Large bundles and broken tree-shaking in Shared" issue](#large-bundles) — have separate index files for each component/library in `shared/ui` and `shared/lib` instead of one big one
150
-
2. Avoid having index files in segments on layers that have slices.
154
+
2. Avoid having index files in segments on layers that have slices.
151
155
For example, if you have an index for the feature "comments", `📄 features/comments/index.js`, there's no reason to have another index for the `ui` segment of that feature, `📄 features/comments/ui/index.js`.
152
-
3. If you have a very big project, there's a good chance that your application can be split into several big chunks.
156
+
3. If you have a very big project, there's a good chance that your application can be split into several big chunks.
153
157
For example, Google Docs has very different responsibilities for the document editor and for the file browser. You can create a monorepo setup where each package is a separate FSD root, with its own set of layers. Some packages can only have the Shared and Entities layers, others might only have Pages and App, others still might include their own small Shared, but still use the big one from another package too.
<imgsrc="../../../../../../static/img/layers/folders-graphic-light.svg"data-theme-only="light"width="180"style={{ float: "right", margin: "0 1em" }}alt="A file system tree, with a single root folder called src and then seven subfolders: app, processes, pages, widgets, features, entities, shared. The processes folder is slightly faded out." />
14
-
<imgsrc="../../../../../../static/img/layers/folders-graphic-dark.svg"data-theme-only="dark"width="180"style={{ float: "right", margin: "0 1em" }}alt="A file system tree, with a single root folder called src and then seven subfolders: app, processes, pages, widgets, features, entities, shared. The processes folder is slightly faded out." />
alt="A file system tree, with a single root folder called src and then seven subfolders: app, processes, pages, widgets, features, entities, shared. The processes folder is slightly faded out."
0 commit comments