Skip to content

Commit fac11e7

Browse files
committed
first release
0 parents  commit fac11e7

File tree

2 files changed

+379
-0
lines changed

2 files changed

+379
-0
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
draft.md

README.md

Lines changed: 378 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,378 @@
1+
# Sliced File Structure
2+
3+
**Sliced FS** — методология разработки файловой структуры проектов. Основана на опыте разработки приложений на React, но подходит для любых проектов на JavaScript.
4+
5+
> #### Перевод на другие языки
6+
>
7+
> Если у вас есть возможность, пожалуйста, внесите свой вклад и помогите перевести этот документ на другие языки, в первую очередь на английский!
8+
9+
## Проблема
10+
11+
Чаще всего в проектах используют **простую файловую структуру**, которая выглядит так — в корневой директории (`src`) создают поддиректории, соответствующие типам ресурсов, используемых в проекте.
12+
13+
Для примера, файловая структура приложения на React может выглядеть так:
14+
15+
> ```sh
16+
> src
17+
> |-- api
18+
> |-- assets
19+
> |-- components
20+
> |-- contexts
21+
> |-- helpers
22+
> |-- hooks
23+
> |-- values
24+
> ```
25+
26+
Такие ресурсы, как компоненты, помещаются в `components`, хелперы в `helpers`, значения в `values` и т.д.
27+
28+
В **маленьких проектах** такая файловая структура обычно подходит и не вызывает проблем.
29+
30+
Но в **средних-больших**, с увеличением количества ресурсов, начинают возникать сложности:
31+
32+
- **Необходимо бороться с коллизиями имён ресурсов**
33+
34+
Поскольку в средних-больших проектах много ресурсов, рано или поздно возникает проблема коллизий имён. Обычно её решают двумя способами.
35+
36+
Первый способ — держать ресурсы на одном уровне вложенности, но усложнить их имена. Например, добавить префиксы.
37+
38+
Недостаток этого подхода заключается в том, что со временем формируются длинные списки ресурсов. Их **долго листать**, в них **сложно найти** нужное. А сложные имена **менее удобно читать** и **использовать**.
39+
40+
> ```sh
41+
> components
42+
> |-- basic-feature-content
43+
> |-- basic-feature-viewer
44+
> |-- (...ещё 30 директорий, начинающихся с "basic-feature")
45+
> |-- experimental-feature-info
46+
> |-- experimental-feature-view-grid
47+
> |-- experimental-feature-view-list
48+
> |-- (...ещё 15 директорий, начинающихся с "experimental-feature")
49+
> |-- pro-feature-editor
50+
> |-- (...ещё 10 директорий, начинающихся с "pro-feature")
51+
> ```
52+
53+
Второй способ — использовать несколько уровней вложенности.
54+
55+
Недостаток этого подхода заключается в том, что возникает неконтролируемая вложенность. Она **усложняет навигацию** по проекту и **оценку комплексности проекта и отдельного функционала**.
56+
57+
> ```sh
58+
> # с виду довольно просто, да?
59+
>
60+
> components
61+
> |-- basic-feature
62+
> |-- experimental-feature
63+
> |-- pro-feature
64+
> ```
65+
66+
> ```sh
67+
> # не тут-то было!
68+
>
69+
> components
70+
> |-- basic-feature
71+
> | |-- content
72+
> | |-- viewer
73+
> |-- experimental-feature
74+
> | |-- info
75+
> | |-- view
76+
> | |-- grid
77+
> | |-- list
78+
> |-- pro-feature
79+
> |-- editor
80+
> ```
81+
82+
- **Сложно отследить связи между ресурсами**
83+
84+
Если вы работаете над некоторым функционалом в средних-крупных проектах, **понять, какие ресурсы относятся к этому функционалу, и где они располагаются — сложно**. Это происходит из-за слабой группировки ресурсов. Чаще всего, единственный вариант — изучить исходный код и составить представление в голове.
85+
86+
Эта проблема в разной степени усугубляется, в зависимости от того, какой способ борьбы с коллизиями имён вы выбрали — сложные имена и длинные списки или вложенные директории.
87+
88+
## Решение
89+
90+
**Sliced FS** вводит несколько терминов (**супергруппы**, **группы**) и определяет некоторые правила, чтобы решить эту проблему. Подходит для любых проектов на JavaScript.
91+
92+
Что это даёт:
93+
94+
* в значительной степени решается проблема коллизий имён ресурсов
95+
* без сложных имён и длинных списков
96+
* без неконтролируемой вложенности
97+
* более сильная группировка ресурсов
98+
* возможность визуально изучить, какие ресурсы относятся к определённому функционалу, без изучения исходного кода (приблизительно)
99+
* возможность визуально оценить комплексность проекта в целом и отдельного фунционала (приблизительно)
100+
101+
Файловая структура проекта на React, разработанная с применением **Sliced FS**, может выглядеть так:
102+
103+
> ```sh
104+
> # в src содержатся супергруппы
105+
>
106+
> src
107+
> |-- basic-feature
108+
> |-- basic-feature.content
109+
> |-- basic-feature.shared
110+
> |-- basic-feature.viewer
111+
> |-- experimental-feature
112+
> |-- experimental-feature.info
113+
> |-- experimental-feature.shared
114+
> |-- experimental-feature.view.grid
115+
> |-- experimental-feature.view.list
116+
> |-- pro-feature
117+
> |-- pro-feature.editor
118+
> ```
119+
120+
> ```sh
121+
> # каждая супергруппа содержит обычные группы
122+
>
123+
> experimental-feature
124+
> |-- api
125+
> |-- assets
126+
> |-- components
127+
> |-- components.editor
128+
> |-- components.content.audio
129+
> |-- components.content.image
130+
> |-- components.content.video
131+
> |-- contexts
132+
> |-- helpers
133+
> |-- hooks
134+
> |-- values
135+
> |-- index.js
136+
> ```
137+
138+
## Концепция
139+
140+
### Супергруппа
141+
142+
Директория, которая содержит в себе обычные **группы**, любые ресурсы вне групп и индексный модуль. Создаёт новое пространство имён.
143+
144+
> ```sh
145+
> # пример супергруппы
146+
>
147+
> src
148+
> |-- basic-feature
149+
> |-- api
150+
> |-- assets
151+
> |-- components
152+
> |-- contexts
153+
> |-- helpers
154+
> |-- hooks
155+
> |-- values
156+
> |-- config.js
157+
> |-- index.js
158+
> ```
159+
160+
#### Расположение
161+
162+
Супергруппы располагаются в корневой директории (`src`).
163+
164+
> ```sh
165+
> src
166+
> |-- basic-feature
167+
> |-- basic-feature.content
168+
> |-- basic-feature.shared
169+
> |-- basic-feature.viewer
170+
> |-- experimental-feature
171+
> |-- experimental-feature.info
172+
> |-- experimental-feature.shared
173+
> |-- experimental-feature.view.grid
174+
> |-- experimental-feature.view.list
175+
> |-- pro-feature
176+
> |-- pro-feature.editor
177+
> ```
178+
179+
#### Вложенность
180+
181+
Супергруппы могут быть вложенными. Вложенность выражается на уровне **имён директорий**, через перечисление цепочки родительских супергрупп через точку.
182+
183+
> ```sh
184+
> src
185+
> |-- experimental-feature
186+
> |-- experimental-feature.info
187+
> |-- experimental-feature.shared
188+
> |-- experimental-feature.view.grid
189+
> |-- experimental-feature.view.list
190+
> ```
191+
192+
#### Ограничения
193+
194+
Супергруппы имеют ограничение на **импорт своих внутренних ресурсов** — любые ресурсы, которые будут использоваться снаружи супергруппы, должны экспортироваться через индексный модуль. **Нельзя обращаться к ресурсам напрямую**, в обход индексного модуля.
195+
196+
> `basic-feature/components/layout`:
197+
>
198+
> ```js
199+
> // ✅ так можно
200+
>
201+
> import ExperimentalFeature from '../../../experimental-feature';
202+
>
203+
> // ❌ так нельзя, обращение к внутренним ресурсам
204+
>
205+
> import Layout from '../../../experimental-feature/components/layout';
206+
> ```
207+
208+
Также, супергруппы имеют ограничение на **импорт из других супергрупп** — нельзя импортировать в дочерней супергруппе ресурсы из родительской супергруппы.
209+
210+
> `experimental-feature/components/layout`:
211+
>
212+
> ```js
213+
> // ✅ так можно
214+
>
215+
> import Content from '../../../experimental-feature.content';
216+
> ```
217+
218+
> `experimental-feature.content/components/content`:
219+
>
220+
> ```js
221+
> // ❌ так нельзя, обращение к ресурсам родительской супергруппы из дочерней супергруппы
222+
>
223+
> import ExperimentalFeature from '../../../experimental-feature';
224+
> ```
225+
226+
#### Супергруппы `shared`
227+
228+
Есть исключение — супергруппы `shared`.
229+
230+
Из такой супергруппы можно импортировать ресурсы напрямую, в обход индексного модуля, но только в её **родительской супергруппе**, а также во всех её **вложенных супергруппах**.
231+
232+
Из этого следует:
233+
234+
- нельзя импортировать ресурсы в супергруппах выше родителя
235+
- ресурсы супергруппы `shared` в корне можно импортировать везде
236+
237+
Супергруппы `shared` **не могут иметь вложенные супергруппы**.
238+
239+
> `basic-feature/components/layout`:
240+
>
241+
> ```js
242+
> // ✅ так можно
243+
>
244+
> import Input from '../../../basic-feature.shared/components/input';
245+
> ```
246+
247+
> `basic-feature.content/components/content`:
248+
>
249+
> ```js
250+
> // ✅ так можно
251+
>
252+
> import Input from '../../../basic-feature.shared/components/input';
253+
> ```
254+
255+
> `experimental-feature/components/layout`:
256+
>
257+
> ```js
258+
> // ❌ так нельзя, обращение к ресурсам чужой shared-супергруппы
259+
>
260+
> import Input from '../../../basic-feature.shared/components/input';
261+
> ```
262+
263+
### Группа
264+
265+
Директория, которая содержит в себе ресурсы. Создаёт новое пространство имён.
266+
267+
> ```sh
268+
> # супергруппа "experimental-feature" содержит обычные группы
269+
>
270+
> experimental-feature
271+
> |-- api
272+
> |-- assets
273+
> |-- components
274+
> |-- components.editor
275+
> |-- components.content.audio
276+
> |-- components.content.image
277+
> |-- components.content.video
278+
> |-- contexts
279+
> |-- helpers
280+
> |-- hooks
281+
> |-- values
282+
> |-- index.js
283+
> ```
284+
285+
#### Расположение
286+
287+
Группы располагаются внутри супергрупп.
288+
289+
#### Вложенность
290+
291+
Группы могут быть вложенными. Вложенность выражается на уровне **имён директорий**, через перечисление цепочки родительских групп через точку.
292+
293+
> ```sh
294+
> experimental-feature
295+
> |-- components
296+
> |-- components.editor
297+
> |-- components.content.audio
298+
> |-- components.content.image
299+
> |-- components.content.video
300+
> ```
301+
302+
#### Ограничения
303+
304+
Группы имеют ограничение на **импорт из других групп** — нельзя импортировать в дочерней группе ресурсы из родительской группы.
305+
306+
> `experimental-feature/components/content`:
307+
>
308+
> ```js
309+
> // ✅ так можно
310+
>
311+
> import Editor from '../../components.editor/editor';
312+
> ```
313+
314+
> `experimental-feature/components.editor/editor`:
315+
>
316+
> ```js
317+
> // ❌ так нельзя, обращение к ресурсам родительской группы из дочерней группы
318+
>
319+
> import Content from '../../components/content';
320+
> ```
321+
322+
#### Группы `shared`
323+
324+
Есть исключение — группы `shared`.
325+
326+
Из такой группы можно импортировать ресурсы как в **родительской группе**, так и во всех её **вложенных группах**.
327+
328+
Из этого следует:
329+
330+
- нельзя импортировать ресурсы в группах выше родителя
331+
332+
Группы `shared` **не могут иметь вложенные группы**.
333+
334+
> `experimental-feature/components/layout`:
335+
>
336+
> ```js
337+
> // ✅ так можно
338+
>
339+
> import Button from '../../components.shared/button';
340+
> ```
341+
342+
> `experimental-feature/components.editor/editor`:
343+
>
344+
> ```js
345+
> // ✅ так можно
346+
>
347+
> import Button from '../../components.shared/button';
348+
> ```
349+
350+
> `experimental-feature/helpers/render-actions.js`:
351+
>
352+
> ```js
353+
> // ❌ так нельзя, обращение к ресурсам чужой shared-группы
354+
>
355+
> import Button from '../../components.shared/button';
356+
> ```
357+
358+
## FAQ
359+
360+
#### Можно ли использовать Sliced FS с TypeScript?
361+
362+
Да!
363+
364+
#### Можно ли использовать Sliced FS с CommonJS?
365+
366+
Да! Только синтаксис модулей будет отличаться.
367+
368+
#### Можно ли использовать Sliced FS с другими языками?
369+
370+
Полагаю, что да! Только система модулей в вашем языке может значительно отличаться. Если у вас получится, пожалуйста, поделитесть опытом в issues.
371+
372+
## Обратная связь
373+
374+
Буду рад любой обратной связи! Пожалуйста, отправляйте её в issues.
375+
376+
## Поддержать автора
377+
378+
[тут будут ссылочки на сторонние ресурсы]

0 commit comments

Comments
 (0)