Skip to content

Commit 34898a2

Browse files
authored
Update with-nuxtjs.mdx
Обновил руководство по использованию FSD с NuxtJS, т.к. текущее руководство не покрывает всю арзитектуру и создает недопонимания в комьюнити. Также разработал свой модуль, который предоставляет конфигурацию из коробки. Если у вас есть рекомендации по улучшению гайда и модуля, буду рад их прочитать.
1 parent 83ce619 commit 34898a2

File tree

1 file changed

+193
-116
lines changed

1 file changed

+193
-116
lines changed

i18n/ru/docusaurus-plugin-content-docs/current/guides/tech/with-nuxtjs.mdx

Lines changed: 193 additions & 116 deletions
Original file line numberDiff line numberDiff line change
@@ -7,173 +7,250 @@ sidebar_position: 10
77

88
- Изначально, NuxtJS предлагает файловую структуру проекта без папки `src`, то есть в корне проекта.
99
- Файловый роутинг находится в папке `pages`, а в FSD эта папка отведена под плоскую структуру слайсов.
10+
- Автоимпорты работают для всех компонентов, в то время как FSD пропагандирует концепцию Public API (делится только необходимым из index файлов).
1011

12+
Но NuxtJS обладает довольно гибкой настройкой конфигурации, что поможет нам полноценно внедрить в него FSD, не теряя его основных достоинств со стороны разработки:
1113

12-
## Добавление алиаса для `src` директории
14+
- Автоимпорты.
15+
- Файловый роутинг.
1316

14-
Добавьте обьект `alias` в ваш конфиг:
15-
```ts title="nuxt.config.ts"
16-
export default defineNuxtConfig({
17-
devtools: { enabled: true }, // Не относятся к FSD, включёны при старте проекта
18-
alias: {
19-
"@": '../src'
20-
},
21-
})
22-
```
23-
## Выбор способа настройки роутера
17+
## Автоимпорты
2418

25-
В NuxtJS есть два способа настройки роутинга - с помощью конфига и с помощью файловой структуры.
26-
В случае с файловым роутингом вы будете создавать index.vue файлы в папках внутри директории app/routes, а в случае конфига - настраивать роуты в `router.options.ts` файле.
19+
На первый взгляд автоимпорты противоречат концепции Public Api и FSD, т.к. создает импорты для всех компонентов, но этого можно избежать, правильно настроив конфигурацию.
2720

21+
### Компоненты
2822

29-
### Роутинг с помощью конфига
23+
По умолчанию в NuxtJS для компонентов выделена дирректория `components/`.
3024

31-
В слое `app` создайте файл `router.options.ts`, и экспортируйте из него обьект конфига:
32-
```ts title="app/router.options.ts"
33-
import type { RouterConfig } from '@nuxt/schema';
25+
Дирректории для компонентов можно переопределить настройкой `components`.
3426

35-
export default <RouterConfig> {
36-
routes: (_routes) => [],
37-
};
27+
#### shared
3828

29+
```ts
30+
components: {
31+
dirs: [
32+
{
33+
path: "~/src/shared", // shared дирректория
34+
pattern: "**/*index.vue", // Файл для автоимпорта
35+
extensions: ["vue"],
36+
},
37+
];
38+
}
3939
```
4040

41-
Чтобы добавить страницу `Home` в проект, вам нужно сделать следующие шаги:
42-
- Добавить слайс страницы внутри слоя `pages`
43-
- Добавить соответствующий роут в конфиг `app/router.config.ts`
41+
#### entities
4442

43+
```ts
44+
components: {
45+
dirs: [
46+
{
47+
path: "~/src/entities", // entities дирректория
48+
extendComponent(component) {
49+
component.pascalName = component.pascalName.replaceAll("Ui", ""); // Убираем Ui дирректории из имени компонента
50+
return component;
51+
},
52+
pattern: "**/*index.vue", // Файл для автоимпорта
53+
extensions: ["vue"],
54+
},
55+
];
56+
}
57+
```
4558

46-
Для того чтобы создать слайс страницы, воспользуемся [CLI](https://github.com/feature-sliced/cli):
59+
#### features
4760

48-
```shell
49-
fsd pages home
61+
```ts
62+
components: {
63+
dirs: [
64+
{
65+
path: "~/src/features", // features дирректория
66+
extendComponent(component) {
67+
component.pascalName = component.pascalName.replaceAll("Ui", ""); // Убираем Ui дирректории из имени компонента
68+
component.pascalName = component.pascalName + "Feature"; // Добавляем Feature постфикс
69+
return component;
70+
},
71+
pattern: "**/*index.vue", // Файл для автоимпорта
72+
extensions: ["vue"],
73+
},
74+
];
75+
}
5076
```
5177

52-
Создайте файл `home-page.vue` внутри сегмента ui, откройте к нему доступ с помощью Public API
78+
#### widgets
5379

54-
```ts title="src/pages/home/index.ts"
55-
export { default as HomePage } from './ui/home-page';
80+
```ts
81+
components: {
82+
dirs: [
83+
{
84+
path: "~/src/widgets", // widgets дирректория
85+
extendComponent(component) {
86+
component.pascalName = component.pascalName.replaceAll("Ui", ""); // Убираем Ui дирректории из имени компонента
87+
component.pascalName = component.pascalName + "Widget"; // Добавляем Widget постфикс
88+
return component;
89+
},
90+
pattern: "**/*index.vue", // Файл для автоимпорта
91+
extensions: ["vue"],
92+
},
93+
];
94+
}
5695
```
5796

58-
Таким образом, файловая структура будет выглядеть так:
59-
```sh
60-
|── src
61-
│ ├── app
62-
│ │ ├── router.config.ts
63-
│ ├── pages
64-
│ │ ├── home
65-
│ │ │ ├── ui
66-
│ │ │ │ ├── home-page.vue
67-
│ │ │ ├── index.ts
97+
#### pages
98+
99+
```ts
100+
components: {
101+
dirs: [
102+
{
103+
path: "~/src/pages", // pages дирректория
104+
pattern: "**/*index.vue", // Файл для автоимпорта
105+
extensions: ["vue"],
106+
},
107+
];
108+
}
68109
```
69-
Наконец, добавим роут в конфиг:
70110

71-
```ts title="app/router.config.ts"
72-
import type { RouterConfig } from '@nuxt/schema'
111+
### Типы, функции и т.п.
73112

74-
export default <RouterConfig> {
75-
routes: (_routes) => [
76-
{
77-
name: 'home',
78-
path: '/',
79-
component: () => import('@/pages/home.vue').then(r => r.default || r)
80-
}
113+
По умолчанию в NuxtJS для этого выделена дирректория `utils/` и т.п.
114+
115+
Такие дирректории можно переопределить настройкой `imports`.
116+
117+
```ts
118+
imports: {
119+
dirs: [
120+
"./src/widgets/*/*/index.ts", // Автоимпорты для widgets слоя
121+
"./src/features/*/*/index.ts", // Автоимпорты для features слоя
122+
"./src/entities/*/*/index.ts", // Автоимпорты для entities слоя
123+
"./src/shared/*/index.ts", // Автоимпорты для shared слоя
81124
],
82125
}
83126
```
84127

85-
### Файловый роутинг
128+
### Использование
86129

87-
В первую очередь, создайте `src` директорию в корне проекта, а также создайте внутри этой директории слои app и pages и папку routes внутри слоя app.
88-
Таким образом, ваша файловая структура должна выглядеть так:
130+
1. Создайте `src` дирректорию.
131+
2. Добавьте в `src` дирректорию FSD слои.
89132

90-
```sh
91-
├── src
92-
│ ├── app
93-
│ │ ├── routes
94-
│ ├── pages # Папка pages, закреплённая за FSD
133+
```bash
134+
.../
135+
├── src/
136+
│ ├── app/
137+
│ ├── entities/
138+
│ ├── features/
139+
│ ├── shared/
140+
│ ├── widgets/
95141
```
96142

97-
Для того чтобы NuxtJS использовал папку routes внутри слоя `app` для файлового роутинга, вам нужно изменить `nuxt.config.ts` следующим образом:
98-
```ts title="nuxt.config.ts"
99-
export default defineNuxtConfig({
100-
devtools: { enabled: true }, // Не относятся к FSD, включёны при старте проекта
101-
alias: {
102-
"@": '../src'
103-
},
104-
dir: {
105-
pages: './src/app/routes'
106-
}
107-
})
143+
#### shared
144+
145+
Рассмотрим компонент `UiButton` для примера.
146+
147+
##### Структурв папок
148+
149+
```bash
150+
.../
151+
├── src/
152+
│ ├── shared/
153+
│ │ ├── ui/
154+
│ │ │ ├── button/
155+
│ │ │ │ ├── interfaces/
156+
│ │ │ │ │ ├── ...
157+
│ │ │ │ ├── index.ts # Для автоимпортов типов компонента
158+
│ │ │ │ ├── index.vue # Для автоимпорта компонента
159+
│ │ ├── utils/ # Любой сегмент
160+
│ │ │ ├── sum.ts
161+
│ │ │ ├── index.ts # Для автоимпорта функции и т.п. сегмента
108162
```
109163

110-
Теперь, вы можете создавать роуты для страниц внутри `app` и подключать к ним страницы из `pages`.
164+
`ui/button/index.ts` - файл для автоимпорта типов компонента.
111165

112-
Например, чтобы добавить страницу `Home` в проект, вам нужно сделать следующие шаги:
113-
- Добавить слайс страницы внутри слоя `pages`
114-
- Добавить соответствующий роут внутрь слоя `app`
115-
- Совместить страницу из слайса с роутом
166+
```ts
167+
export type { IUiButtonProps } from "./interfaces";
168+
```
116169

117-
Для того чтобы создать слайс страницы, воспользуемся [CLI](https://github.com/feature-sliced/cli):
170+
`ui/button/index.vue` - файл для автоимпорта компонента.
118171

119-
```shell
120-
fsd pages home
121-
```
172+
```vue
173+
<script setup lang="ts">
174+
import type { IUiButtonProps } from "./interfaces";
122175
123-
Создайте файл `home-page.vue` внутри сегмента ui, откройте к нему доступ с помощью Public API
176+
const props = withDefaults(defineProps<IUiButtonProps>(), {
177+
type: "button",
178+
});
179+
</script>
124180
125-
```ts title="src/pages/home/index.ts"
126-
export { default as HomePage } from './ui/home-page';
181+
<template>
182+
<button :type="type">
183+
<slot />
184+
</button>
185+
</template>
127186
```
128187

129-
Создайте роут для этой страницы внутри слоя `app`:
188+
`utils/index.ts` - файл для автоимпорта функции и т.п. сегмента.
130189

131-
```sh
132-
133-
├── src
134-
│ ├── app
135-
│ │ ├── routes
136-
│ │ │ ├── index.vue
137-
│ ├── pages
138-
│ │ ├── home
139-
│ │ │ ├── ui
140-
│ │ │ │ ├── home-page.vue
141-
│ │ │ ├── index.ts
190+
```ts
191+
export { sum } from "./sum";
142192
```
143193

144-
Добавьте внутрь `index.vue` файла компонент вашей страницы:
194+
##### Использование
145195

146-
```html title="src/app/routes/index.vue"
147-
<script setup>
148-
import { HomePage } from '@/pages/home';
196+
```vue
197+
<script setup lang="ts">
198+
const props: IUiButtonProps = {
199+
type: "submit",
200+
};
149201
</script>
150202
151203
<template>
152-
<HomePage/>
204+
<UiButton v-bind="props"> Total: {{ sum(1, 4) }} </UiButton>
153205
</template>
154206
```
155207

156-
## Что делать с `layouts`?
157-
158-
Вы можете разместить layouts внутри слоя `app`, для этого нужно изменить конфиг следующим образом:
159-
160-
```ts title="nuxt.config.ts"
161-
export default defineNuxtConfig({
162-
devtools: { enabled: true }, // Не относятся к FSD, включёны при старте проекта
163-
alias: {
164-
"@": '../src'
165-
},
166-
dir: {
167-
pages: './src/app/routes',
168-
layouts: './src/app/layouts'
169-
}
170-
})
208+
#### entities
209+
210+
Все также, как с `shared`, но компоненты не имеют `Ui` префикса и в структуру папок добавляется папка `слайса`.
211+
212+
#### features, widgets
213+
214+
Все также, как с `entities`, но компоненты имеют `Feature` и `Widget` постфикс.
215+
216+
#### pages
217+
218+
```bash
219+
.../
220+
├── src/
221+
│ ├── pages/
222+
│ │ ├── product/ # Любая страница
223+
│ │ │ ├── index.vue # Для автоимпорта компонента страницы
224+
```
225+
226+
## Роутинг, шаблоны, middleware
227+
228+
Необходимо переопределить дирректории по умолчанию.
229+
230+
```ts
231+
dir: {
232+
pages: "./src/app/routes", // Роутинг
233+
layouts: "./src/app/layouts", // Шаблоны
234+
middleware: "./src/app/middlewares", // middlewares
235+
},
171236
```
172237

238+
### app
239+
240+
```bash
241+
.../
242+
├── src/
243+
│ ├── app/
244+
│ │ ├── routes/ # Роуты приложения
245+
│ │ │ ├── index.vue # Роут для пути "/"
246+
│ │ ├── middlewares/ # Middleware приложения
247+
│ │ │ ├── auth.ts # Middleware авторизации
248+
│ │ ├── layouts/ # Шаблоны приложения
249+
│ │ │ ├── default.vue # Шаблон приложения по умолчанию
250+
```
173251

174-
## См. также
252+
## Хочешь начать быстрее
175253

176-
- [Документация по изменению конфига директорий в NuxtJS](https://nuxt.com/docs/api/nuxt-config#dir)
177-
- [Документация по изменению конфига роутера в NuxtJS](https://nuxt.com/docs/guide/recipes/custom-routing#router-config)
178-
- [Документация по изменению алиасов в NuxtJS](https://nuxt.com/docs/api/nuxt-config#alias)
254+
Чтобы не настраивать все вручную, можно использовать модуль, который автоматически меняет конфигурацию.
179255

256+
[@dand.dev/nuxt-fsd](https://www.npmjs.com/package/@dand.dev/nuxt-fsd)

0 commit comments

Comments
 (0)