From 29bcf23dded0a14c15a233f9520e98c3acc91c74 Mon Sep 17 00:00:00 2001 From: "S.Gromov" Date: Wed, 1 Apr 2026 10:35:07 +0300 Subject: [PATCH] =?UTF-8?q?docs:=20=D0=BF=D0=B5=D1=80=D0=B5=D1=80=D0=B0?= =?UTF-8?q?=D0=B1=D0=BE=D1=82=D0=B0=D1=82=D1=8C=20=D0=BA=D0=BE=D0=BC=D0=BF?= =?UTF-8?q?=D0=BE=D0=BD=D0=B5=D0=BD=D1=82=D1=8B,=20=D1=81=D1=82=D1=80?= =?UTF-8?q?=D1=83=D0=BA=D1=82=D1=83=D1=80=D1=83=20=D0=BF=D1=80=D0=BE=D0=B5?= =?UTF-8?q?=D0=BA=D1=82=D0=B0=20=D0=B8=20=D0=B4=D0=BE=D0=BA=D1=83=D0=BC?= =?UTF-8?q?=D0=B5=D0=BD=D1=82=D0=B8=D1=80=D0=BE=D0=B2=D0=B0=D0=BD=D0=B8?= =?UTF-8?q?=D0=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - переработан раздел «Компоненты»: добавлены правила организации, типизации, реализации - переработан раздел «Структура проекта»: упрощён, добавлены корень репозитория и конфиг-файлы - переработан раздел «Документирование»: добавлены шаблоны для функций, компонентов, типов - обновлён CONTRIBUTING.md: добавлены секции Workflow и Чеклист, правила разделены на Реализацию и Организацию - перенесены типы компонентов из «Типизации» в «Компоненты» - обновлён шаблон генерации: деструктуризация пропсов в теле, children вместо текста - добавлен SCREAMING_SNAKE_CASE для ключей enum в «Именование» - перемещён «Настройка VS Code» в конец сайдбара - обновлён порядок файлов в concat-md.js и перегенерирован RULES.md --- .vitepress/config.ts | 5 +- CONTRIBUTING.md | 59 ++- concat-md.js | 2 +- docs/ru/applied/components.md | 88 ++-- docs/ru/applied/project-structure.md | 204 +++----- docs/ru/applied/templates-generation.md | 6 +- docs/ru/basics/documentation.md | 140 +++-- docs/ru/basics/naming.md | 1 + docs/ru/basics/typing.md | 39 -- generated/ru/RULES.md | 663 ++++++++++++------------ 10 files changed, 614 insertions(+), 593 deletions(-) diff --git a/.vitepress/config.ts b/.vitepress/config.ts index 5394386..e2cf104 100644 --- a/.vitepress/config.ts +++ b/.vitepress/config.ts @@ -19,10 +19,8 @@ const ruSidebar = [ { text: 'Прикладные разделы', items: [ - { text: 'Настройка VS Code', link: '/applied/vscode' }, { text: 'Структура проекта', link: '/applied/project-structure' }, - { text: 'UI и компоненты', link: '/applied/components' }, - { text: 'Компоненты (new)', link: '/applied/components-new' }, + { text: 'Компоненты', link: '/applied/components' }, { text: 'Страницы (App Router)', link: '/applied/page-level' }, { text: 'Шаблоны и генерация кода', link: '/applied/templates-generation' }, { text: 'Стили', link: '/applied/styles' }, @@ -34,6 +32,7 @@ const ruSidebar = [ { text: 'Хуки', link: '/applied/hooks' }, { text: 'Шрифты', link: '/applied/fonts' }, { text: 'Локализация', link: '/applied/localization' }, + { text: 'Настройка VS Code', link: '/applied/vscode' }, ], }, ]; diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index ed12f3f..fda91df 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -25,7 +25,6 @@ docs/ ├── ru/ # Русская версия (основная) │ ├── index.md # Главная страница -│ ├── workflow.md # Workflow (единый файл) │ ├── basics/ # Базовые правила │ │ ├── tech-stack.md │ │ ├── architecture.md @@ -63,16 +62,7 @@ concat-md.js # Скрипт генерации RULES.md 2. Добавить пункт в сайдбар — `.vitepress/config.ts` (оба языка, если есть перевод). 3. Добавить файл в массив `fileOrder` — `concat-md.js` (для генерации RULES.md). -## Три типа документации - -### Workflow - -**Отвечает на вопрос:** «Что делать и в каком порядке?» - -Пошаговые инструкции. Описывает процесс, а не правила. -Не содержит развёрнутых примеров кода — только минимальные команды и шаги. - -Живёт в одном файле `workflow.md`. +## Два типа документации ### Базовые правила @@ -105,8 +95,8 @@ concat-md.js # Скрипт генерации RULES.md ## Что нужно знать -Контекст перед правилами: технологии, термины, принципы работы. -Не правила — фундамент, без которого правила будут непонятны. +Неочевидная информация, которую читатель должен знать перед чтением раздела. +Если для раздела нет такой вводной — секция не создаётся. ## Структура @@ -115,9 +105,25 @@ concat-md.js # Скрипт генерации RULES.md ## Правила -Конкретные требования к реализации в этой области. -Формат — маркированный или нумерованный список. +Конкретные требования, специфичные для области. Делятся на две подсекции: + +### Реализация + +Как написан код внутри файла: синтаксис, паттерны, API. +Отвечает на вопрос: «Как писать код?» + +Примеры: объявление через `const`, деструктуризация пропсов, формат вызова `cl()`, способ подключения стилей, структура хука. + +### Организация + +Как компонент/модуль встроен в проект: файловые границы, зоны ответственности, экспорт. +Отвечает на вопрос: «Где что лежит и за что отвечает?» + +Примеры: один компонент — один файл, вложенные компоненты в `ui/`, логика выносится в `model/`. + +Формат обеих подсекций — маркированный список. Для неочевидных случаев — блоки «Хорошо / Плохо». +Если в области нет правил одной из категорий — подсекция не создаётся. ## Именование @@ -138,12 +144,29 @@ concat-md.js # Скрипт генерации RULES.md Полноценные примеры кода. Каждый пример с путём к файлу и пояснениями. + +## Workflow (процессы) + +Пошаговая инструкция: как работать с этой областью на практике. +Отвечает на вопрос: «Что делать и в каком порядке?» +Нумерованный список шагов. Минимум кода — только команды и имена файлов. +Не дублирует правила — описывает процесс, а не результат. +Если для области нет специфичного процесса — секция не создаётся. + +## Чеклист + +Контрольный список для проверки перед завершением работы. +Отвечает на вопрос: «Всё ли я сделал правильно?» +Формат — маркированный список с чекбоксами (`- [ ]`). +Каждый пункт — конкретная проверка, а не пересказ правила. +Если для области нет специфичных проверок — секция не создаётся. ``` ### Порядок секций -Порядок фиксированный: контекст → структура → правила → специализации базовых правил → примеры. -Логика: читатель сначала понимает «что это», потом «где это лежит», потом «как это делать», и в конце видит полный пример. +Порядок фиксированный: контекст → структура → правила → специализации базовых правил → примеры → процесс → проверка. + +Логика: читатель сначала понимает «что это», потом «где это лежит», потом «как это делать», видит полный пример, получает пошаговую инструкцию и в конце проверяет себя по чеклисту. ### Секции-расширения базовых правил @@ -215,6 +238,6 @@ title: Название раздела 1. **Не дублировать.** Одна мысль живёт в одном месте. Остальные ссылаются. 2. **Базовое vs прикладное.** Если правило применимо ко всему коду — оно базовое. Если только к одной области — прикладное. -3. **Workflow vs правила.** Workflow описывает процесс (шаги). Правила описывают результат (каким должен быть код). +3. **Workflow vs правила.** Workflow описывает процесс (шаги), правила описывают результат (каким должен быть код). Оба живут внутри прикладного раздела, но не смешиваются. 4. **Пустые секции не создавать.** Если для раздела нет специфики по именованию — секции «Именование» в нём нет. 5. **Примеры обязательны.** Прикладной раздел без примеров кода — незавершён. diff --git a/concat-md.js b/concat-md.js index 5bcf6a6..b1f89e9 100644 --- a/concat-md.js +++ b/concat-md.js @@ -15,7 +15,6 @@ const fileOrder = [ "basics/documentation.md", "basics/typing.md", // applied - "applied/vscode.md", "applied/project-structure.md", "applied/components.md", "applied/page-level.md", @@ -29,6 +28,7 @@ const fileOrder = [ "applied/hooks.md", "applied/fonts.md", "applied/localization.md", + "applied/vscode.md", ]; // Удалить frontmatter из содержимого md-файла diff --git a/docs/ru/applied/components.md b/docs/ru/applied/components.md index 96d2fda..56f7180 100644 --- a/docs/ru/applied/components.md +++ b/docs/ru/applied/components.md @@ -1,10 +1,20 @@ --- -title: UI и компоненты +title: Компоненты --- -# UI и компоненты +# Компоненты -Раздел описывает правила создания UI‑компонентов. Эти правила обязательны для всех слоёв FSD: `app`, `screens`, `layouts`, `widgets`, `features`, `entities`, `shared`. +Правила написания React-компонентов: файловая структура модуля, типизация пропсов, документирование и реализация. Раздел охватывает компоненты всех слоёв — от `shared/ui` до `screens`. + +Архитектурные слои и их назначение описаны в разделе [Архитектура](/basics/architecture). + + +## Правила организации + +1. Один компонент — один файл. +2. Компонент не содержит бизнес-логики — логика и сайд-эффекты выносятся в хуки или сторы. +3. Дочерние компоненты размещаются в сегменте `ui/` и подчиняются тем же правилам структуры. +4. Публичный API модуля — только `index.ts`. Прямые импорты внутренних файлов запрещены. ## Базовая структура компонента @@ -20,26 +30,48 @@ container/ └── index.ts ``` -## Пример базового компонента +## Именования -`styles/container.module.css` -```scss -.root {} -``` -В CSS Modules использование имени класса **.root** — это общепринятое соглашение (best practice) +- Имя корневого css класса всегда `.root` +- Интерфейс именуется `{ComponentName}Props`. + +## Типизация + +- Компонент типизируется через `FC`. +- Интерфейс пропсов наследует HTML-атрибуты своего корневого элемента. +- `children` отдельно не объявляется — приходит из `HTMLAttributes`. + +## Реализация + +- Пропсы деструктурируются в теле компонента, не в параметрах. +- Порядок: пользовательские → системные (`children`, `className`) → `...htmlAttr`. +- `className` объединяется с корневым классом через `cl()`: `cl(styles.root, className)`. +- `...htmlAttr` прокидывается на корневой элемент. + +## Пример + +`container/types/container.interface.ts` -`types/container.interface.ts` ```ts import type { HTMLAttributes } from 'react' /** - * Параметры контейнера. + * Параметры компонента Container. */ export interface ContainerProps extends HTMLAttributes {} ``` -Интерфес параметров компонента всегда наследует свойства своего тега: div, button, итд.. -`container.tsx` +`container/styles/container.module.css` + +```css +.root { + max-width: var(--content-width); + margin: 0 auto; + padding: 0 var(--spacing-4); +} +``` + +`container/container.tsx` ```tsx import type { FC } from 'react' @@ -51,39 +83,23 @@ import styles from './styles/container.module.css' * Контейнер с адаптивной максимальной шириной. * * Используется для: - * - ограничения ширины контента - * - центрирования содержимого - * - построения адаптивной сетки страницы + * - обёртки контента страниц с ограничением ширины + * - центрирования блоков в лейауте */ -export const Container: FC = ({ className, ...htmlAttr }) => { +export const Container: FC = (props) => { + const { children, className, ...htmlAttr } = props + return (
- Container... + {children}
) } ``` -- Компонент объявляется через `const` и экспортируется именованно. -- Пропсы деструктурируются в сигнатуре; если их больше двух — деструктуризацию переносим в тело компонента. -- Из пропсов отдельно извлекаются `className` и `...htmlAttr`, чтобы корректно объединять классы и прокидывать остальные атрибуты. -- `cl` — короткое имя функции для конкатенации CSS‑классов. -- `FC<>` используется для декларации `children`. - -`index.ts` +`container/index.ts` ```ts export { Container } from './container' ``` -## Шаблоны и генерация кода - -Создание компонентов — **только через шаблоны**. Ручное создание файловой структуры компонента запрещено. Это обеспечивает единообразие каркаса, одинаковые папки и имена файлов, уменьшает ручные ошибки и ускоряет старт работы. - -После генерации через **@gromlab/create** — проверить название компонента/файлов и заполнить описание назначения. Подробный порядок действий и перечень обязательных шаблонов — в разделе «Workflow». - -## Вложенные (дочерние) компоненты - -Если для реализации функционала нужны компоненты, которые используются только внутри текущего компонента, создавайте их как вложенные в папке `ui/`. Такие компоненты не экспортируются наружу и используются только локально. - -Вложенные компоненты подчиняются тем же правилам по структуре, именованию и стилю (включая папку `styles/` для их стилей). diff --git a/docs/ru/applied/project-structure.md b/docs/ru/applied/project-structure.md index 44bf1cb..fbd63ca 100644 --- a/docs/ru/applied/project-structure.md +++ b/docs/ru/applied/project-structure.md @@ -4,146 +4,96 @@ title: Структура проекта # Структура проекта -Раздел описывает базовую структуру проекта Next.js (App Router) и принципы организации модулей на уровне папок и файлов. +Раздел описывает расположение файлов и папок в проекте Next.js (App Router). -## Базовая структура проекта +## Корень репозитория + +```text +project-root/ +├── .templates/ # Шаблоны для генерации модулей +├── .vscode/ # Настройки и рекомендуемые расширения VS Code +├── public/ # Статика, доступная по прямому URL +├── src/ # Исходный код приложения +├── .env.example # Переменные окружения проекта (шаблон) +├── .env # Переменные окружения проекта (не коммитить) +├── .gitignore +├── AGENTS.md # Инструкции для AI-агентов +├── biome.json # Линтер и форматтер (вместо ESLint + Prettier) +├── next.config.ts # Конфигурация Next.js +├── package.json # Зависимости и скрипты +├── postcss.config.mjs # Конфигурация PostCSS +└── tsconfig.json # Конфигурация TypeScript +``` + +## Папка `public/` + +Хранит статические файлы, которые отдаются по прямому URL без обработки сборщиком: + +```text +public/ +└── og-image.png +``` + +Компоненты, стили и другой исходный код здесь не размещаются. + +## Папка `src/` ```text src/ -├── app/ # Слой app: роутинг, провайдеры, глобальные стили -│ ├── providers/ # Провайдеры и обёртки приложения -│ ├── styles/ # Глобальные стили, CSS-переменные, custom media -│ ├── layout.tsx # Корневой layout (провайдеры, стили, метаданные) -│ ├── page.tsx # Главная страница → HomeScreen -│ └── profile/ -│ ├── page.tsx # → ProfileScreen -│ └── [id]/ -│ └── page.tsx # → ProfileDetailScreen -├── screens/ # UI-компоненты страниц -│ ├── home/ -│ │ ├── home.screen.tsx -│ │ └── index.ts -│ └── profile/ -│ ├── profile.screen.tsx -│ └── index.ts -├── layouts/ # Общие шаблоны и каркасы страниц -│ └── main-layout/ -│ ├── main-layout.layout.tsx -│ └── index.ts -├── widgets/ # Крупные блоки интерфейса -│ └── header/ -│ ├── header.widget.tsx -│ └── index.ts -├── features/ # Пользовательские сценарии -│ └── auth-by-email/ -│ ├── ui/ -│ │ └── login-form.tsx -│ ├── model/ -│ │ └── auth-by-email.store.ts -│ ├── auth-by-email.feature.tsx -│ └── index.ts -├── entities/ # Бизнес-сущности -│ └── user/ -│ ├── model/ -│ │ └── user.store.ts -│ ├── user.entity.tsx -│ └── index.ts -└── shared/ # Общие ресурсы проекта - ├── ui/ # Повторно используемые UI-элементы - │ └── icon/ - │ ├── styles/ - │ │ └── icon.module.css - │ ├── types/ - │ │ └── icon.interface.ts - │ ├── icon.tsx - │ └── index.ts - ├── lib/ # Утилиты и хелперы - ├── services/ # Общие сервисы и клиенты - ├── config/ # Общие конфигурации и константы - └── assets/ # Ресурсы - ├── images/ - ├── icons/ - ├── fonts/ - └── video/ +├── app/ # Роутинг Next.js, провайдеры, глобальные стили +├── screens/ # Собраные страницы (UI) +├── layouts/ # Шаблоны +├── widgets/ # Крупные самостоятельные блоки интерфейса +├── features/ # Пользовательские сценарии +├── entities/ # Бизнес-сущности +└── shared/ # Переиспользуемый код (UI, утилиты, типы и др.) ``` -## Слой `app/` +Принципы организации слоёв описаны в разделе [Архитектура](../basics/architecture). -Папка `app/` совмещает две роли: инициализация приложения (провайдеры, глобальные стили) и файловый роутинг Next.js (route-сегменты, `layout.tsx`, `page.tsx`). +### Папка `app/` -- `providers/` и `styles/` -- это инфраструктура приложения, они не являются частью роутинга. -- Route-сегменты (вложенные папки с `page.tsx`) -- это роутинг Next.js. Они не содержат логики, только импортируют экраны из `screens/`. +Совмещает два слоя: инициализацию приложения по FSD (провайдеры, глобальные стили) и файловый роутинг Next.js (`layout.tsx`, `page.tsx`, route-сегменты). -Компоненты, хуки, стили и утилиты не размещаются внутри route-сегментов -- всё это живёт в соответствующих слоях FSD. - -## Правила организации - -- В слоях FSD (`features`, `entities`, `widgets`, `screens` и т.д.) `ui/` используется только для дочерних элементов, которые относятся к модулю и не экспортируются отдельно. Главные компоненты, которые составляют сам слой, держат собственные `*.feature.tsx`, `*.widget.tsx` и т. п., а `ui/` служит для вспомогательных мелких компонентов. -- В `shared/ui/` хранятся базовые UI-элементы/компоненты, которыми пользуются сразу несколько модулей; в этом случае они экспортируются наружу и не считаются «дочерними» для слоя. -- Если модуль строится вокруг «главного» компонента (`*.feature.tsx`, `*.screen.tsx`, `*.widget.tsx`), помещайте его в корень модуля и экспортируйте через `index.ts`. Проверяйте, что `ui/` не используется просто как «контейнер» слоя. -- Каждый слой и модуль хранится в собственной папке. -- Внутренние реализации разделяются на `ui/`, `model/`, `styles/`, `helpers/`, `lib/`, `api/`. -- Публичный API модуля объявляется в `index.ts`. -- Внутренние файлы не импортируются напрямую извне. -- Не смешивать ответственность разных слоёв в одном модуле. - -## Пример организации структуры - -**Плохо** -- плоская структура без архитектуры: ```text -src/ -├── components/ -│ ├── Header.tsx -│ ├── LoginForm.tsx -│ ├── UserCard.tsx -│ └── Button.tsx -├── hooks/ -│ ├── useAuth.ts -│ └── useUser.ts -├── api/ -│ ├── auth.ts -│ └── user.ts -├── styles/ -│ ├── header.module.css -│ └── login.module.css -├── types/ -│ └── user.ts -└── utils/ - └── format.ts +src/app/ +├── providers/ # Провайдеры приложения +├── styles/ # Глобальные стили +├── layout.tsx # Корневой layout +└── page.tsx # Главная страница ``` -Нет слоёв, нет границ ответственности -- Header и Button лежат рядом, хотя это разные уровни абстракции. LoginForm знает про API напрямую. При росте проекта `components/` превращается в свалку. +## Папка `.templates/` + +Содержит шаблоны для генерации кода. Каждый подкаталог — шаблон отдельного типа модуля: -**Хорошо** -- та же функциональность в FSD: ```text -src/ -├── widgets/ -│ └── header/ -│ ├── header.widget.tsx -│ └── index.ts -├── features/ -│ └── auth-by-email/ -│ ├── ui/ -│ │ └── login-form.tsx -│ ├── model/ -│ │ └── auth.store.ts -│ ├── auth-by-email.feature.tsx -│ └── index.ts -├── entities/ -│ └── user/ -│ ├── ui/ -│ │ └── user-card.tsx -│ ├── model/ -│ │ └── user.store.ts -│ ├── user.entity.tsx -│ └── index.ts -└── shared/ - ├── ui/ - │ └── button/ - │ ├── button.tsx - │ └── index.ts - └── lib/ - └── format.ts +.templates/ +├── component/ # Шаблон компонента +├── screen/ # Шаблон экрана +├── layout/ # Шаблон layout +├── widget/ # Шаблон виджета +├── feature/ # Шаблон фичи +├── entity/ # Шаблон сущности +└── store/ # Шаблон стора ``` -Каждый элемент на своём слое, с публичным API и чёткими границами ответственности. +Подробнее о генерации описано в разделе [Шаблоны и генерация кода](./templates-generation). + +## Конфигурационные файлы + +| Файл | Назначение | +|---|---| +| `next.config.ts` | Настройки Next.js: редиректы, переменные окружения, webpack | +| `tsconfig.json` | Настройки TypeScript: пути, строгость, таргет | +| `biome.json` | Правила линтера и форматтера Biome | +| `postcss.config.mjs` | Подключение PostCSS-плагинов (CSS Modules, custom media) | +| `package.json` | Зависимости, версии, npm-скрипты | +| `AGENTS.md` | Инструкции для AI-агентов, работающих в проекте | + +## Переменные окружения + +- `.env` — переменные окружения проекта, запрещено коммитить +- `.env.example` — шаблон, коммитится в репозиторий + +Переменные с префиксом `NEXT_PUBLIC_` доступны в клиентском коде. Остальные доступны только на сервере. diff --git a/docs/ru/applied/templates-generation.md b/docs/ru/applied/templates-generation.md index 2fbada3..3ae013f 100644 --- a/docs/ru/applied/templates-generation.md +++ b/docs/ru/applied/templates-generation.md @@ -105,10 +105,12 @@ import styles from './styles/{{name.kebabCase}}.module.css' /** * {{name.pascalCase}}. */ -export const {{name.pascalCase}}: FC<{{name.pascalCase}}Props> = ({ className, ...htmlAttr }) => { +export const {{name.pascalCase}}: FC<{{name.pascalCase}}Props> = (props) => { + const { children, className, ...htmlAttr } = props + return (
- {{name.kebabCase}} + {children}
) } diff --git a/docs/ru/basics/documentation.md b/docs/ru/basics/documentation.md index f392acc..d4e9c61 100644 --- a/docs/ru/basics/documentation.md +++ b/docs/ru/basics/documentation.md @@ -4,61 +4,131 @@ title: Документирование # Документирование -Этот раздел описывает правила документирования кода: когда и как писать комментарии к функциям, компонентам, типам и интерфейсам. +Этот раздел описывает правила документирования кода: когда и как писать +комментарии к компонентам, функциям, типам и интерфейсам. -## Правила +## Общие правила -- Документировать только назначение функций, компонентов, типов, интерфейсов и enum. -- Не документировать параметры, возвращаемые значения, типы пропсов и очевидные детали. -- В интерфейсах, типах и enum описывать только смысл поля или значения. -- Описание должно быть кратким, информативным и завершаться точкой. +- Документировать публичные функции, компоненты, типы, интерфейсы и enum. +- Не документировать очевидное — если название говорит само за себя, комментарий не нужен. +- Не документировать параметры, возвращаемые значения и типы пропсов — они видны из сигнатуры. +- Описание через пользу и назначение, а не через внутреннюю реализацию. +- Описание завершается точкой. -## Примеры +## Функции + +Для документирования функций используется шаблон. Описание механики опционально — +добавляется когда логика нетривиальна. + +**Шаблон** +```ts +/** + * <Что делает функция в 1 строке>. + * + * <Опционально: описание сложной механики или важных нюансов>. + */ +``` **Хорошо** ```ts /** - * Список задач пользователя. + * Форматирует цену с символом валюты. */ -export const TodoList = memo(() => { ... }); +export const formatPrice = (value: number): string => { ... } /** - * Интерфейс задачи. + * Рекурсивно собирает дерево категорий из плоского списка. + * + * Группирует элементы по parentId, начиная с корневых (parentId = null). + * Категории без родителя попадают в корень дерева. + */ +export const buildCategoryTree = (categories: Category[]): CategoryTree[] => { ... } +``` + +**Плохо** +```ts +// Плохо: дублирует сигнатуру. +/** + * @param value - число + * @returns строка с ценой + */ +``` + +## Компоненты + +Компонент описывает своё **назначение** и **сценарии применения** — это помогает понять, когда и где его использовать, без необходимости читать реализацию. + +**Шаблон** +```ts +/** + * <Назначение компонента в 1 строке>. + * + * Используется для: + * - <сценарий 1> + * - <сценарий 2> + * - <сценарий 3> + */ +``` + +**Хорошо** +```tsx +/** + * Контейнер с адаптивной максимальной шириной. + * + * Используется для: + * - обёртки контента страниц с ограничением ширины + * - центрирования блоков в лейауте + */ +export const Container: FC = (props) => { ... } +``` + +**Плохо** +```tsx +// Плохо: описывает реализацию, а не назначение. +/** + * Рендерит div с className и htmlAttr. + */ + +// Плохо: нет описания вообще. +export const Container: FC = (props) => { ... } +``` + +## Типы, интерфейсы, enum + +Документируются назначение сущности и каждое её поле. + +**Хорошо** +```ts +/** + * Фильтры списка задач. + */ +export enum TodoFilter { + /** Все задачи. */ + ALL = 'all', + /** Только активные. */ + ACTIVE = 'active', + /** Только завершённые. */ + COMPLETED = 'completed', +} + +/** + * Задача пользователя. */ export interface TodoItem { /** Уникальный идентификатор задачи. */ id: string; /** Текст задачи. */ text: string; - /** Статус выполнения задачи. */ + /** Статус выполнения. */ completed: boolean; } - -/** - * Перечисление фильтров задач. - */ -export enum TodoFilter { - /** Все задачи. */ - All = 'all', - /** Только активные задачи. */ - Active = 'active', - /** Только выполненные задачи. */ - Completed = 'completed', -} ``` **Плохо** ```ts -// Плохо: дублирование параметров и возвращаемых значений. -/** - * @param id - идентификатор задачи - * @returns объект задачи - */ - -// Плохо: описание очевидных деталей. -/** - * id — идентификатор задачи - * text — текст задачи - * completed — статус выполнения - */ +// Плохо: описывает очевидное. +export interface TodoItem { + /** id — это id */ + id: string; +} ``` diff --git a/docs/ru/basics/naming.md b/docs/ru/basics/naming.md index 31fa5f0..e2d7867 100644 --- a/docs/ru/basics/naming.md +++ b/docs/ru/basics/naming.md @@ -18,6 +18,7 @@ title: Именование | React-компоненты | `PascalCase` | | Хуки | `useSomething` | | CSS классы | `camelCase` | +| Ключи enum | `SCREAMING_SNAKE_CASE` | ## Именование файлов diff --git a/docs/ru/basics/typing.md b/docs/ru/basics/typing.md index b4b1f6f..3da8967 100644 --- a/docs/ru/basics/typing.md +++ b/docs/ru/basics/typing.md @@ -13,45 +13,6 @@ title: Типизация - Избегать `any` и `unknown` без необходимости. - Не использовать `ts-ignore`, кроме крайних случаев с явным комментарием причины. -## Типы для компонентов - -- Типизировать параметры и публичный интерфейс компонента. -- Дефолтные значения описывать явно в коде. - -**Хорошо** -```tsx -/** - * Параметры кнопки. - */ -interface ButtonProps extends HTMLAttributes { - /** Текст кнопки. */ - label: string; - /** Обработчик клика по кнопке. */ - onClick: () => void; -} - -/** - * Кнопка с пользовательскими стилями. - */ -export const Button: FC = ({ className, label, onClick, ...htmlAttr }) => { - return ( -
- button -
- ) -} -``` - -**Плохо** -```tsx -// Плохо: параметры не типизированы. -export const Button = (props) => ( - -); -``` - ## Функции - Для публичных функций указывать возвращаемый тип. diff --git a/generated/ru/RULES.md b/generated/ru/RULES.md index d28c344..dd9e444 100644 --- a/generated/ru/RULES.md +++ b/generated/ru/RULES.md @@ -200,6 +200,7 @@ | React-компоненты | `PascalCase` | | Хуки | `useSomething` | | CSS классы | `camelCase` | +| Ключи enum | `SCREAMING_SNAKE_CASE` | ### Именование файлов @@ -540,63 +541,133 @@ const config = { url: '/api/users', method: 'GET', params: { page: 1, pageSize: ## Документирование -Этот раздел описывает правила документирования кода: когда и как писать комментарии к функциям, компонентам, типам и интерфейсам. +Этот раздел описывает правила документирования кода: когда и как писать +комментарии к компонентам, функциям, типам и интерфейсам. -### Правила +### Общие правила -- Документировать только назначение функций, компонентов, типов, интерфейсов и enum. -- Не документировать параметры, возвращаемые значения, типы пропсов и очевидные детали. -- В интерфейсах, типах и enum описывать только смысл поля или значения. -- Описание должно быть кратким, информативным и завершаться точкой. +- Документировать публичные функции, компоненты, типы, интерфейсы и enum. +- Не документировать очевидное — если название говорит само за себя, комментарий не нужен. +- Не документировать параметры, возвращаемые значения и типы пропсов — они видны из сигнатуры. +- Описание через пользу и назначение, а не через внутреннюю реализацию. +- Описание завершается точкой. -### Примеры +### Функции + +Для документирования функций используется шаблон. Описание механики опционально — +добавляется когда логика нетривиальна. + +**Шаблон** +```ts +/** + * <Что делает функция в 1 строке>. + * + * <Опционально: описание сложной механики или важных нюансов>. + */ +``` **Хорошо** ```ts /** - * Список задач пользователя. + * Форматирует цену с символом валюты. */ -export const TodoList = memo(() => { ... }); +export const formatPrice = (value: number): string => { ... } /** - * Интерфейс задачи. + * Рекурсивно собирает дерево категорий из плоского списка. + * + * Группирует элементы по parentId, начиная с корневых (parentId = null). + * Категории без родителя попадают в корень дерева. + */ +export const buildCategoryTree = (categories: Category[]): CategoryTree[] => { ... } +``` + +**Плохо** +```ts +// Плохо: дублирует сигнатуру. +/** + * @param value - число + * @returns строка с ценой + */ +``` + +### Компоненты + +Компонент описывает своё **назначение** и **сценарии применения** — это помогает понять, когда и где его использовать, без необходимости читать реализацию. + +**Шаблон** +```ts +/** + * <Назначение компонента в 1 строке>. + * + * Используется для: + * - <сценарий 1> + * - <сценарий 2> + * - <сценарий 3> + */ +``` + +**Хорошо** +```tsx +/** + * Контейнер с адаптивной максимальной шириной. + * + * Используется для: + * - обёртки контента страниц с ограничением ширины + * - центрирования блоков в лейауте + */ +export const Container: FC = (props) => { ... } +``` + +**Плохо** +```tsx +// Плохо: описывает реализацию, а не назначение. +/** + * Рендерит div с className и htmlAttr. + */ + +// Плохо: нет описания вообще. +export const Container: FC = (props) => { ... } +``` + +### Типы, интерфейсы, enum + +Документируются назначение сущности и каждое её поле. + +**Хорошо** +```ts +/** + * Фильтры списка задач. + */ +export enum TodoFilter { + /** Все задачи. */ + ALL = 'all', + /** Только активные. */ + ACTIVE = 'active', + /** Только завершённые. */ + COMPLETED = 'completed', +} + +/** + * Задача пользователя. */ export interface TodoItem { /** Уникальный идентификатор задачи. */ id: string; /** Текст задачи. */ text: string; - /** Статус выполнения задачи. */ + /** Статус выполнения. */ completed: boolean; } - -/** - * Перечисление фильтров задач. - */ -export enum TodoFilter { - /** Все задачи. */ - All = 'all', - /** Только активные задачи. */ - Active = 'active', - /** Только выполненные задачи. */ - Completed = 'completed', -} ``` **Плохо** ```ts -// Плохо: дублирование параметров и возвращаемых значений. -/** - * @param id - идентификатор задачи - * @returns объект задачи - */ - -// Плохо: описание очевидных деталей. -/** - * id — идентификатор задачи - * text — текст задачи - * completed — статус выполнения - */ +// Плохо: описывает очевидное. +export interface TodoItem { + /** id — это id */ + id: string; +} ``` @@ -611,45 +682,6 @@ export enum TodoFilter { - Избегать `any` и `unknown` без необходимости. - Не использовать `ts-ignore`, кроме крайних случаев с явным комментарием причины. -### Типы для компонентов - -- Типизировать параметры и публичный интерфейс компонента. -- Дефолтные значения описывать явно в коде. - -**Хорошо** -```tsx -/** - * Параметры кнопки. - */ -interface ButtonProps extends HTMLAttributes { - /** Текст кнопки. */ - label: string; - /** Обработчик клика по кнопке. */ - onClick: () => void; -} - -/** - * Кнопка с пользовательскими стилями. - */ -export const Button: FC = ({ className, label, onClick, ...htmlAttr }) => { - return ( -
- button -
- ) -} -``` - -**Плохо** -```tsx -// Плохо: параметры не типизированы. -export const Button = (props) => ( - -); -``` - ### Функции - Для публичных функций указывать возвращаемый тип. @@ -692,242 +724,117 @@ const parse = (value: unknown): string => { const parse = (value: any) => value; ``` - -## Настройка VS Code - -Каждый проект содержит папку `.vscode/` с конфигурацией редактора. Это гарантирует, что все участники команды работают с одинаковыми настройками форматирования, линтинга и расширениями. - -### Структура `.vscode/` - -```text -.vscode/ -├── extensions.json # Рекомендуемые расширения -└── settings.json # Настройки редактора для проекта -``` - -Оба файла коммитятся в репозиторий. - -### Расширения - -Файл `.vscode/extensions.json` определяет список расширений, которые VS Code предложит установить при открытии проекта. - -```json -// .vscode/extensions.json -{ - "recommendations": [ - "biomejs.biome", - "MyTemplateGenerator.mytemplategenerator", - "csstools.postcss" - ] -} -``` - -| Расширение | Назначение | -|---|---| -| [Biome](https://marketplace.visualstudio.com/items?itemName=biomejs.biome) | Линтинг и форматирование кода. Заменяет ESLint и Prettier | -| [MyTemplateGenerator](https://open-vsx.org/extension/MyTemplateGenerator/mytemplategenerator) | Генерация файлов и папок из шаблонов `.templates/` через контекстное меню | -| [PostCSS Language Support](https://marketplace.visualstudio.com/items?itemName=csstools.postcss) | Подсветка синтаксиса и автодополнение для PostCSS (`@custom-media`, `@nest` и др.) | - -#### Зачем это нужно - -- Новый участник команды получает все нужные расширения одним кликом. -- Нет разночтений: все используют одинаковый форматтер и линтер. -- Расширения привязаны к проекту, а не к конкретному разработчику. - -### Настройки редактора - -Файл `.vscode/settings.json` переопределяет пользовательские настройки VS Code на уровне проекта. - -```json -// .vscode/settings.json -{ - "editor.defaultFormatter": "biomejs.biome", - "editor.formatOnSave": true, - "editor.codeActionsOnSave": { - "source.fixAll.biome": "explicit", - "source.organizeImports.biome": "explicit" - }, - "files.associations": { - "*.css": "postcss" - } -} -``` - -#### Разбор настроек - -| Настройка | Значение | Что делает | -|---|---|---| -| `editor.defaultFormatter` | `biomejs.biome` | Biome используется как единственный форматтер для всех файлов | -| `editor.formatOnSave` | `true` | Код автоматически форматируется при каждом сохранении | -| `codeActionsOnSave.source.fixAll.biome` | `explicit` | Biome автоматически применяет безопасные исправления при сохранении | -| `codeActionsOnSave.source.organizeImports.biome` | `explicit` | Импорты сортируются и группируются автоматически при сохранении | -| `files.associations` | `"*.css": "postcss"` | Все CSS-файлы открываются с подсветкой PostCSS вместо стандартного CSS | - -#### Зачем это нужно - -- **Единый стиль кода** -- форматирование происходит автоматически, невозможно закоммитить неформатированный код. -- **Автофикс при сохранении** -- распространённые ошибки линтинга исправляются без ручного вмешательства. -- **Сортировка импортов** -- импорты всегда в одном порядке, без конфликтов при мерже. -- **PostCSS-подсветка** -- кастомные at-правила (`@custom-media`, `@define-mixin`) подсвечиваются корректно, а не как ошибки. - -### Что не должно быть в `.vscode/` - -Не коммитятся файлы, специфичные для конкретного разработчика: - -- **Не коммитить**: отладочные конфигурации с локальными путями, персональные сниппеты, настройки тем оформления. -- **Коммитить**: только `extensions.json` и `settings.json` с общими для команды настройками. - ## Структура проекта -Раздел описывает базовую структуру проекта Next.js (App Router) и принципы организации модулей на уровне папок и файлов. +Раздел описывает расположение файлов и папок в проекте Next.js (App Router). -### Базовая структура проекта +### Корень репозитория + +```text +project-root/ +├── .templates/ # Шаблоны для генерации модулей +├── .vscode/ # Настройки и рекомендуемые расширения VS Code +├── public/ # Статика, доступная по прямому URL +├── src/ # Исходный код приложения +├── .env.example # Переменные окружения проекта (шаблон) +├── .env # Переменные окружения проекта (не коммитить) +├── .gitignore +├── AGENTS.md # Инструкции для AI-агентов +├── biome.json # Линтер и форматтер (вместо ESLint + Prettier) +├── next.config.ts # Конфигурация Next.js +├── package.json # Зависимости и скрипты +├── postcss.config.mjs # Конфигурация PostCSS +└── tsconfig.json # Конфигурация TypeScript +``` + +### Папка `public/` + +Хранит статические файлы, которые отдаются по прямому URL без обработки сборщиком: + +```text +public/ +└── og-image.png +``` + +Компоненты, стили и другой исходный код здесь не размещаются. + +### Папка `src/` ```text src/ -├── app/ # Слой app: роутинг, провайдеры, глобальные стили -│ ├── providers/ # Провайдеры и обёртки приложения -│ ├── styles/ # Глобальные стили, CSS-переменные, custom media -│ ├── layout.tsx # Корневой layout (провайдеры, стили, метаданные) -│ ├── page.tsx # Главная страница → HomeScreen -│ └── profile/ -│ ├── page.tsx # → ProfileScreen -│ └── [id]/ -│ └── page.tsx # → ProfileDetailScreen -├── screens/ # UI-компоненты страниц -│ ├── home/ -│ │ ├── home.screen.tsx -│ │ └── index.ts -│ └── profile/ -│ ├── profile.screen.tsx -│ └── index.ts -├── layouts/ # Общие шаблоны и каркасы страниц -│ └── main-layout/ -│ ├── main-layout.layout.tsx -│ └── index.ts -├── widgets/ # Крупные блоки интерфейса -│ └── header/ -│ ├── header.widget.tsx -│ └── index.ts -├── features/ # Пользовательские сценарии -│ └── auth-by-email/ -│ ├── ui/ -│ │ └── login-form.tsx -│ ├── model/ -│ │ └── auth-by-email.store.ts -│ ├── auth-by-email.feature.tsx -│ └── index.ts -├── entities/ # Бизнес-сущности -│ └── user/ -│ ├── model/ -│ │ └── user.store.ts -│ ├── user.entity.tsx -│ └── index.ts -└── shared/ # Общие ресурсы проекта - ├── ui/ # Повторно используемые UI-элементы - │ └── icon/ - │ ├── styles/ - │ │ └── icon.module.css - │ ├── types/ - │ │ └── icon.interface.ts - │ ├── icon.tsx - │ └── index.ts - ├── lib/ # Утилиты и хелперы - ├── services/ # Общие сервисы и клиенты - ├── config/ # Общие конфигурации и константы - └── assets/ # Ресурсы - ├── images/ - ├── icons/ - ├── fonts/ - └── video/ +├── app/ # Роутинг Next.js, провайдеры, глобальные стили +├── screens/ # Собраные страницы (UI) +├── layouts/ # Шаблоны +├── widgets/ # Крупные самостоятельные блоки интерфейса +├── features/ # Пользовательские сценарии +├── entities/ # Бизнес-сущности +└── shared/ # Переиспользуемый код (UI, утилиты, типы и др.) ``` -### Слой `app/` +Принципы организации слоёв описаны в разделе [Архитектура](../basics/architecture). -Папка `app/` совмещает две роли: инициализация приложения (провайдеры, глобальные стили) и файловый роутинг Next.js (route-сегменты, `layout.tsx`, `page.tsx`). +#### Папка `app/` -- `providers/` и `styles/` -- это инфраструктура приложения, они не являются частью роутинга. -- Route-сегменты (вложенные папки с `page.tsx`) -- это роутинг Next.js. Они не содержат логики, только импортируют экраны из `screens/`. +Совмещает два слоя: инициализацию приложения по FSD (провайдеры, глобальные стили) и файловый роутинг Next.js (`layout.tsx`, `page.tsx`, route-сегменты). + +```text +src/app/ +├── providers/ # Провайдеры приложения +├── styles/ # Глобальные стили +├── layout.tsx # Корневой layout +└── page.tsx # Главная страница +``` + +### Папка `.templates/` + +Содержит шаблоны для генерации кода. Каждый подкаталог — шаблон отдельного типа модуля: + +```text +.templates/ +├── component/ # Шаблон компонента +├── screen/ # Шаблон экрана +├── layout/ # Шаблон layout +├── widget/ # Шаблон виджета +├── feature/ # Шаблон фичи +├── entity/ # Шаблон сущности +└── store/ # Шаблон стора +``` + +Подробнее о генерации описано в разделе [Шаблоны и генерация кода](./templates-generation). + +### Конфигурационные файлы + +| Файл | Назначение | +|---|---| +| `next.config.ts` | Настройки Next.js: редиректы, переменные окружения, webpack | +| `tsconfig.json` | Настройки TypeScript: пути, строгость, таргет | +| `biome.json` | Правила линтера и форматтера Biome | +| `postcss.config.mjs` | Подключение PostCSS-плагинов (CSS Modules, custom media) | +| `package.json` | Зависимости, версии, npm-скрипты | +| `AGENTS.md` | Инструкции для AI-агентов, работающих в проекте | + +### Переменные окружения + +- `.env` — переменные окружения проекта, запрещено коммитить +- `.env.example` — шаблон, коммитится в репозиторий + +Переменные с префиксом `NEXT_PUBLIC_` доступны в клиентском коде. Остальные доступны только на сервере. + + +## Компоненты + +Правила написания React-компонентов: файловая структура модуля, типизация пропсов, документирование и реализация. Раздел охватывает компоненты всех слоёв — от `shared/ui` до `screens`. + +Архитектурные слои и их назначение описаны в разделе [Архитектура](/basics/architecture). -Компоненты, хуки, стили и утилиты не размещаются внутри route-сегментов -- всё это живёт в соответствующих слоях FSD. ### Правила организации -- В слоях FSD (`features`, `entities`, `widgets`, `screens` и т.д.) `ui/` используется только для дочерних элементов, которые относятся к модулю и не экспортируются отдельно. Главные компоненты, которые составляют сам слой, держат собственные `*.feature.tsx`, `*.widget.tsx` и т. п., а `ui/` служит для вспомогательных мелких компонентов. -- В `shared/ui/` хранятся базовые UI-элементы/компоненты, которыми пользуются сразу несколько модулей; в этом случае они экспортируются наружу и не считаются «дочерними» для слоя. -- Если модуль строится вокруг «главного» компонента (`*.feature.tsx`, `*.screen.tsx`, `*.widget.tsx`), помещайте его в корень модуля и экспортируйте через `index.ts`. Проверяйте, что `ui/` не используется просто как «контейнер» слоя. -- Каждый слой и модуль хранится в собственной папке. -- Внутренние реализации разделяются на `ui/`, `model/`, `styles/`, `helpers/`, `lib/`, `api/`. -- Публичный API модуля объявляется в `index.ts`. -- Внутренние файлы не импортируются напрямую извне. -- Не смешивать ответственность разных слоёв в одном модуле. - -### Пример организации структуры - -**Плохо** -- плоская структура без архитектуры: -```text -src/ -├── components/ -│ ├── Header.tsx -│ ├── LoginForm.tsx -│ ├── UserCard.tsx -│ └── Button.tsx -├── hooks/ -│ ├── useAuth.ts -│ └── useUser.ts -├── api/ -│ ├── auth.ts -│ └── user.ts -├── styles/ -│ ├── header.module.css -│ └── login.module.css -├── types/ -│ └── user.ts -└── utils/ - └── format.ts -``` - -Нет слоёв, нет границ ответственности -- Header и Button лежат рядом, хотя это разные уровни абстракции. LoginForm знает про API напрямую. При росте проекта `components/` превращается в свалку. - -**Хорошо** -- та же функциональность в FSD: -```text -src/ -├── widgets/ -│ └── header/ -│ ├── header.widget.tsx -│ └── index.ts -├── features/ -│ └── auth-by-email/ -│ ├── ui/ -│ │ └── login-form.tsx -│ ├── model/ -│ │ └── auth.store.ts -│ ├── auth-by-email.feature.tsx -│ └── index.ts -├── entities/ -│ └── user/ -│ ├── ui/ -│ │ └── user-card.tsx -│ ├── model/ -│ │ └── user.store.ts -│ ├── user.entity.tsx -│ └── index.ts -└── shared/ - ├── ui/ - │ └── button/ - │ ├── button.tsx - │ └── index.ts - └── lib/ - └── format.ts -``` - -Каждый элемент на своём слое, с публичным API и чёткими границами ответственности. - - -## UI и компоненты - -Раздел описывает правила создания UI‑компонентов. Эти правила обязательны для всех слоёв FSD: `app`, `screens`, `layouts`, `widgets`, `features`, `entities`, `shared`. +1. Один компонент — один файл. +2. Компонент не содержит бизнес-логики — логика и сайд-эффекты выносятся в хуки или сторы. +3. Дочерние компоненты размещаются в сегменте `ui/` и подчиняются тем же правилам структуры. +4. Публичный API модуля — только `index.ts`. Прямые импорты внутренних файлов запрещены. ### Базовая структура компонента @@ -943,26 +850,48 @@ container/ └── index.ts ``` -### Пример базового компонента +### Именования -`styles/container.module.css` -```scss -.root {} -``` -В CSS Modules использование имени класса **.root** — это общепринятое соглашение (best practice) +- Имя корневого css класса всегда `.root` +- Интерфейс именуется `{ComponentName}Props`. + +### Типизация + +- Компонент типизируется через `FC`. +- Интерфейс пропсов наследует HTML-атрибуты своего корневого элемента. +- `children` отдельно не объявляется — приходит из `HTMLAttributes`. + +### Реализация + +- Пропсы деструктурируются в теле компонента, не в параметрах. +- Порядок: пользовательские → системные (`children`, `className`) → `...htmlAttr`. +- `className` объединяется с корневым классом через `cl()`: `cl(styles.root, className)`. +- `...htmlAttr` прокидывается на корневой элемент. + +### Пример + +`container/types/container.interface.ts` -`types/container.interface.ts` ```ts import type { HTMLAttributes } from 'react' /** - * Параметры контейнера. + * Параметры компонента Container. */ export interface ContainerProps extends HTMLAttributes {} ``` -Интерфес параметров компонента всегда наследует свойства своего тега: div, button, итд.. -`container.tsx` +`container/styles/container.module.css` + +```css +.root { + max-width: var(--content-width); + margin: 0 auto; + padding: 0 var(--spacing-4); +} +``` + +`container/container.tsx` ```tsx import type { FC } from 'react' @@ -974,43 +903,26 @@ import styles from './styles/container.module.css' * Контейнер с адаптивной максимальной шириной. * * Используется для: - * - ограничения ширины контента - * - центрирования содержимого - * - построения адаптивной сетки страницы + * - обёртки контента страниц с ограничением ширины + * - центрирования блоков в лейауте */ -export const Container: FC = ({ className, ...htmlAttr }) => { +export const Container: FC = (props) => { + const { children, className, ...htmlAttr } = props + return (
- Container... + {children}
) } ``` -- Компонент объявляется через `const` и экспортируется именованно. -- Пропсы деструктурируются в сигнатуре; если их больше двух — деструктуризацию переносим в тело компонента. -- Из пропсов отдельно извлекаются `className` и `...htmlAttr`, чтобы корректно объединять классы и прокидывать остальные атрибуты. -- `cl` — короткое имя функции для конкатенации CSS‑классов. -- `FC<>` используется для декларации `children`. - -`index.ts` +`container/index.ts` ```ts export { Container } from './container' ``` -### Шаблоны и генерация кода - -Создание компонентов — **только через шаблоны**. Ручное создание файловой структуры компонента запрещено. Это обеспечивает единообразие каркаса, одинаковые папки и имена файлов, уменьшает ручные ошибки и ускоряет старт работы. - -После генерации через **@gromlab/create** — проверить название компонента/файлов и заполнить описание назначения. Подробный порядок действий и перечень обязательных шаблонов — в разделе «Workflow». - -### Вложенные (дочерние) компоненты - -Если для реализации функционала нужны компоненты, которые используются только внутри текущего компонента, создавайте их как вложенные в папке `ui/`. Такие компоненты не экспортируются наружу и используются только локально. - -Вложенные компоненты подчиняются тем же правилам по структуре, именованию и стилю (включая папку `styles/` для их стилей). - ## Страницы (App Router) @@ -1295,10 +1207,12 @@ import styles from './styles/{{name.kebabCase}}.module.css' /** * {{name.pascalCase}}. */ -export const {{name.pascalCase}}: FC<{{name.pascalCase}}Props> = ({ className, ...htmlAttr }) => { +export const {{name.pascalCase}}: FC<{{name.pascalCase}}Props> = (props) => { + const { children, className, ...htmlAttr } = props + return (
- {{name.kebabCase}} + {children}
) } @@ -1606,4 +1520,89 @@ npx @gromlab/create <шаблон> <имя> <путь> - Исключение — нетривиальные хаки и обходные решения, к которым стоит оставить пояснение. -## SVG-спрайты \ No newline at end of file +## SVG-спрайты + + +## Настройка VS Code + +Каждый проект содержит папку `.vscode/` с конфигурацией редактора. Это гарантирует, что все участники команды работают с одинаковыми настройками форматирования, линтинга и расширениями. + +### Структура `.vscode/` + +```text +.vscode/ +├── extensions.json # Рекомендуемые расширения +└── settings.json # Настройки редактора для проекта +``` + +Оба файла коммитятся в репозиторий. + +### Расширения + +Файл `.vscode/extensions.json` определяет список расширений, которые VS Code предложит установить при открытии проекта. + +```json +// .vscode/extensions.json +{ + "recommendations": [ + "biomejs.biome", + "MyTemplateGenerator.mytemplategenerator", + "csstools.postcss" + ] +} +``` + +| Расширение | Назначение | +|---|---| +| [Biome](https://marketplace.visualstudio.com/items?itemName=biomejs.biome) | Линтинг и форматирование кода. Заменяет ESLint и Prettier | +| [MyTemplateGenerator](https://open-vsx.org/extension/MyTemplateGenerator/mytemplategenerator) | Генерация файлов и папок из шаблонов `.templates/` через контекстное меню | +| [PostCSS Language Support](https://marketplace.visualstudio.com/items?itemName=csstools.postcss) | Подсветка синтаксиса и автодополнение для PostCSS (`@custom-media`, `@nest` и др.) | + +#### Зачем это нужно + +- Новый участник команды получает все нужные расширения одним кликом. +- Нет разночтений: все используют одинаковый форматтер и линтер. +- Расширения привязаны к проекту, а не к конкретному разработчику. + +### Настройки редактора + +Файл `.vscode/settings.json` переопределяет пользовательские настройки VS Code на уровне проекта. + +```json +// .vscode/settings.json +{ + "editor.defaultFormatter": "biomejs.biome", + "editor.formatOnSave": true, + "editor.codeActionsOnSave": { + "source.fixAll.biome": "explicit", + "source.organizeImports.biome": "explicit" + }, + "files.associations": { + "*.css": "postcss" + } +} +``` + +#### Разбор настроек + +| Настройка | Значение | Что делает | +|---|---|---| +| `editor.defaultFormatter` | `biomejs.biome` | Biome используется как единственный форматтер для всех файлов | +| `editor.formatOnSave` | `true` | Код автоматически форматируется при каждом сохранении | +| `codeActionsOnSave.source.fixAll.biome` | `explicit` | Biome автоматически применяет безопасные исправления при сохранении | +| `codeActionsOnSave.source.organizeImports.biome` | `explicit` | Импорты сортируются и группируются автоматически при сохранении | +| `files.associations` | `"*.css": "postcss"` | Все CSS-файлы открываются с подсветкой PostCSS вместо стандартного CSS | + +#### Зачем это нужно + +- **Единый стиль кода** -- форматирование происходит автоматически, невозможно закоммитить неформатированный код. +- **Автофикс при сохранении** -- распространённые ошибки линтинга исправляются без ручного вмешательства. +- **Сортировка импортов** -- импорты всегда в одном порядке, без конфликтов при мерже. +- **PostCSS-подсветка** -- кастомные at-правила (`@custom-media`, `@define-mixin`) подсвечиваются корректно, а не как ошибки. + +### Что не должно быть в `.vscode/` + +Не коммитятся файлы, специфичные для конкретного разработчика: + +- **Не коммитить**: отладочные конфигурации с локальными путями, персональные сниппеты, настройки тем оформления. +- **Коммитить**: только `extensions.json` и `settings.json` с общими для команды настройками. \ No newline at end of file