docs: рефакторинг документации — workflow, прикладные разделы, генерация RULES.md
- Переработан раздел Workflow: заголовки, описания, порядок разделов - Добавлены новые разделы: Генерация кода (workflow), Настройка VS Code (applied) - Убран суффикс .ui.tsx из документации и примеров - Переработан раздел Структура проекта — только Next.js, без React SPA - Приоритет стилизации перенесён из applied/styles в workflow/styling - Убрано дублирование инструментов генерации — единая точка в applied/templates-generation - Переписан concat-md.js: без внешних зависимостей, мета-якоря для навигации в RULES.md - Удалена зависимость concat-md - Обновлена главная страница: названия разделов, URL на RULES.md - Добавлен AGENTS.md с правилами для агентов
This commit is contained in:
@@ -16,7 +16,7 @@ container/
|
||||
│ └── container.module.scss
|
||||
├── types/
|
||||
│ └── container.interface.ts
|
||||
├── container.ui.tsx
|
||||
├── container.tsx
|
||||
└── index.ts
|
||||
```
|
||||
|
||||
@@ -39,7 +39,7 @@ export interface ContainerProps extends HTMLAttributes<HTMLDivElement> {}
|
||||
```
|
||||
Интерфес параметров компонента всегда наследует свойства своего тега: div, button, итд..
|
||||
|
||||
`container.ui.tsx`
|
||||
`container.tsx`
|
||||
|
||||
```tsx
|
||||
import type { FC } from 'react'
|
||||
@@ -73,7 +73,7 @@ export const Container: FC<ContainerProps> = ({ className, ...htmlAttr }) => {
|
||||
`index.ts`
|
||||
|
||||
```ts
|
||||
export { Container } from './container.ui'
|
||||
export { Container } from './container'
|
||||
```
|
||||
|
||||
## Шаблоны и генерация кода
|
||||
|
||||
186
docs/ru/applied/page-level.md
Normal file
186
docs/ru/applied/page-level.md
Normal file
@@ -0,0 +1,186 @@
|
||||
---
|
||||
title: Page-level компоненты
|
||||
---
|
||||
|
||||
# Page-level компоненты
|
||||
|
||||
Специальные файлы Next.js App Router, которые фреймворк использует по соглашению: `layout.tsx`, `page.tsx`, `loading.tsx`, `error.tsx`, `not-found.tsx`, `template.tsx`.
|
||||
|
||||
## Общие правила
|
||||
|
||||
- Экспорт через `export default function` — конвенция Next.js.
|
||||
- Типизация через `PropsWithChildren` или явный интерфейс.
|
||||
- Каждая страница (`page.tsx`) должна содержать `metadata` с `title` и `description`.
|
||||
- Минимум логики — page-level компоненты делегируют работу экранам, виджетам и фичам.
|
||||
- Стили в page-level компонентах не используются — стилизация внутри вызываемых компонентов.
|
||||
|
||||
## layout.tsx
|
||||
|
||||
Корневой layout — точка подключения провайдеров, глобальных стилей и метаданных.
|
||||
|
||||
```tsx
|
||||
import type { PropsWithChildren } from 'react'
|
||||
import type { Metadata } from 'next'
|
||||
import { ColorSchemeScript, MantineProvider } from '@mantine/core'
|
||||
import '@mantine/core/styles.css'
|
||||
import './globals.css'
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: {
|
||||
default: 'App',
|
||||
template: '%s | App',
|
||||
},
|
||||
description: 'Описание приложения',
|
||||
metadataBase: new URL('https://example.com'),
|
||||
openGraph: {
|
||||
type: 'website',
|
||||
locale: 'ru_RU',
|
||||
siteName: 'App',
|
||||
images: [
|
||||
{
|
||||
url: '/og-image.png',
|
||||
width: 1200,
|
||||
height: 630,
|
||||
alt: 'App',
|
||||
},
|
||||
],
|
||||
},
|
||||
twitter: {
|
||||
card: 'summary_large_image',
|
||||
},
|
||||
}
|
||||
|
||||
export default function RootLayout({ children }: PropsWithChildren) {
|
||||
return (
|
||||
<html lang="ru" suppressHydrationWarning>
|
||||
<head>
|
||||
<ColorSchemeScript />
|
||||
</head>
|
||||
<body>
|
||||
<MantineProvider>
|
||||
{children}
|
||||
</MantineProvider>
|
||||
</body>
|
||||
</html>
|
||||
)
|
||||
}
|
||||
```
|
||||
|
||||
Вложенный layout — для секции с общей обёрткой (sidebar, header):
|
||||
|
||||
```tsx
|
||||
import type { PropsWithChildren } from 'react'
|
||||
import { DashboardLayout } from '@/shared/ui/dashboard-layout'
|
||||
|
||||
export default function Layout({ children }: PropsWithChildren) {
|
||||
return (
|
||||
<DashboardLayout>
|
||||
{children}
|
||||
</DashboardLayout>
|
||||
)
|
||||
}
|
||||
```
|
||||
|
||||
## page.tsx
|
||||
|
||||
Тонкий файл — только импорт и рендер экрана. Логика, стили и зависимости размещаются в экране, не в `page.tsx`.
|
||||
|
||||
```tsx
|
||||
import type { Metadata } from 'next'
|
||||
import { HomeScreen } from '@/screens/home'
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: 'Главная',
|
||||
description: 'Главная страница приложения',
|
||||
}
|
||||
|
||||
export default function HomePage() {
|
||||
return <HomeScreen />
|
||||
}
|
||||
```
|
||||
|
||||
С параметрами маршрута:
|
||||
|
||||
```tsx
|
||||
import type { Metadata } from 'next'
|
||||
import { ProfileScreen } from '@/screens/profile'
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: 'Профиль',
|
||||
description: 'Страница профиля пользователя',
|
||||
}
|
||||
|
||||
interface ProfilePageProps {
|
||||
params: Promise<{ id: string }>
|
||||
}
|
||||
|
||||
export default async function ProfilePage({ params }: ProfilePageProps) {
|
||||
const { id } = await params
|
||||
|
||||
return <ProfileScreen id={id} />
|
||||
}
|
||||
```
|
||||
|
||||
Каждая страница должна содержать `metadata` с `title` — он подставится в шаблон из корневого layout: `Профиль | App`.
|
||||
|
||||
## loading.tsx
|
||||
|
||||
Состояние загрузки. Показывается пока загружается контент страницы.
|
||||
|
||||
```tsx
|
||||
export default function Loading() {
|
||||
return <div>Загрузка...</div>
|
||||
}
|
||||
```
|
||||
|
||||
## error.tsx
|
||||
|
||||
Обработка ошибок. Обязательно `'use client'` — error boundary работает только на клиенте. Разметку выносим в экран.
|
||||
|
||||
```tsx
|
||||
'use client'
|
||||
|
||||
import type { FC } from 'react'
|
||||
import { ErrorScreen } from '@/screens/error'
|
||||
|
||||
interface ErrorPageProps {
|
||||
error: Error & { digest?: string }
|
||||
reset: () => void
|
||||
}
|
||||
|
||||
const ErrorPage: FC<ErrorPageProps> = ({ error, reset }) => {
|
||||
return <ErrorScreen error={error} reset={reset} />
|
||||
}
|
||||
|
||||
export default ErrorPage
|
||||
```
|
||||
|
||||
## not-found.tsx
|
||||
|
||||
Страница 404. Показывается когда маршрут не найден. Разметку выносим в экран.
|
||||
|
||||
```tsx
|
||||
import type { Metadata } from 'next'
|
||||
import { NotFoundScreen } from '@/screens/not-found'
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: 'Страница не найдена',
|
||||
description: 'Запрашиваемая страница не существует',
|
||||
}
|
||||
|
||||
export default function NotFound() {
|
||||
return <NotFoundScreen />
|
||||
}
|
||||
```
|
||||
|
||||
## template.tsx
|
||||
|
||||
Аналог layout, но пересоздаётся при каждой навигации (не сохраняет состояние). Используется редко — для анимаций переходов между страницами.
|
||||
|
||||
```tsx
|
||||
import type { PropsWithChildren } from 'react'
|
||||
|
||||
export default function Template({ children }: PropsWithChildren) {
|
||||
return <div>{children}</div>
|
||||
}
|
||||
```
|
||||
@@ -4,16 +4,25 @@ title: Структура проекта
|
||||
|
||||
# Структура проекта
|
||||
|
||||
Раздел описывает базовую структуру проекта и принципы организации модулей на уровне папок и файлов.
|
||||
Раздел описывает базовую структуру проекта Next.js (App Router) и принципы организации модулей на уровне папок и файлов.
|
||||
|
||||
## Базовая структура проекта
|
||||
|
||||
Слои FSD не зависят от фреймворка. Различается только содержимое `app/` — в React SPA это конфигурация роутинга, в Next.js — системные файлы фреймворка (`layout.tsx`, `page.tsx`, route-сегменты).
|
||||
|
||||
```text
|
||||
src/
|
||||
├── app/ # Инициализация приложения (см. «Слой app/»)
|
||||
├── 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
|
||||
@@ -28,7 +37,7 @@ src/
|
||||
├── features/ # Пользовательские сценарии
|
||||
│ └── auth-by-email/
|
||||
│ ├── ui/
|
||||
│ │ └── login-form.ui.tsx
|
||||
│ │ └── login-form.tsx
|
||||
│ ├── model/
|
||||
│ │ └── auth-by-email.store.ts
|
||||
│ ├── auth-by-email.feature.tsx
|
||||
@@ -46,7 +55,7 @@ src/
|
||||
│ │ └── icon.module.css
|
||||
│ ├── types/
|
||||
│ │ └── icon.interface.ts
|
||||
│ ├── icon.ui.tsx
|
||||
│ ├── icon.tsx
|
||||
│ └── index.ts
|
||||
├── lib/ # Утилиты и хелперы
|
||||
├── services/ # Общие сервисы и клиенты
|
||||
@@ -58,61 +67,83 @@ src/
|
||||
└── video/
|
||||
```
|
||||
|
||||
## Слой app/
|
||||
## Слой `app/`
|
||||
|
||||
Общее для обоих вариантов: провайдеры и глобальные стили. Различается только способ организации роутинга.
|
||||
Папка `app/` совмещает две роли: инициализация приложения (провайдеры, глобальные стили) и файловый роутинг Next.js (route-сегменты, `layout.tsx`, `page.tsx`).
|
||||
|
||||
### React SPA
|
||||
- `providers/` и `styles/` -- это инфраструктура приложения, они не являются частью роутинга.
|
||||
- Route-сегменты (вложенные папки с `page.tsx`) -- это роутинг Next.js. Они не содержат логики, только импортируют экраны из `screens/`.
|
||||
|
||||
```text
|
||||
src/app/
|
||||
├── providers/ # Провайдеры и обёртки приложения
|
||||
├── routing/ # Конфигурация маршрутов (React Router)
|
||||
├── styles/ # Глобальные стили, CSS-переменные, custom media
|
||||
└── index.ts # Entry point приложения
|
||||
```
|
||||
|
||||
### Next.js (App Router)
|
||||
|
||||
```text
|
||||
src/app/
|
||||
├── providers/ # Провайдеры и обёртки приложения
|
||||
├── styles/ # Глобальные стили, CSS-переменные, custom media
|
||||
├── layout.tsx # Корневой layout (подключает providers, styles)
|
||||
├── page.tsx # Главная страница
|
||||
└── profile/
|
||||
└── page.tsx # Рендерит ProfileScreen
|
||||
```
|
||||
|
||||
В Next.js файлы `page.tsx` остаются тонкими — они только импортируют экран из `screens/` и рендерят его. Вся логика, зависимости и стили страницы живут в компоненте экрана, а не в `app/`.
|
||||
|
||||
```tsx
|
||||
// src/app/profile/page.tsx
|
||||
import { ProfileScreen } from '@/screens/profile';
|
||||
|
||||
export default function ProfilePage() {
|
||||
return <ProfileScreen />;
|
||||
}
|
||||
```
|
||||
|
||||
**Плохо**
|
||||
```text
|
||||
// Плохо: слои смешаны, нет понятных границ и публичного API.
|
||||
src/
|
||||
├── components/
|
||||
├── api/
|
||||
├── styles/
|
||||
└── user.ts
|
||||
```
|
||||
Компоненты, хуки, стили и утилиты не размещаются внутри route-сегментов -- всё это живёт в соответствующих слоях FSD.
|
||||
|
||||
## Правила организации
|
||||
|
||||
- В слоях FSD (`features`, `entities`, `widgets`, `screens` и т.д.) `ui/` используется только для дочерних элементов, которые относятся к модулю и не экспортируются отдельно. Главные компоненты, которые составляют сам слой, держат собственные `*.feature.tsx`, `*.widget.tsx` и т. п., а `ui/` служит для вспомогательных мелких компонентов.
|
||||
- В слоях 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 и чёткими границами ответственности.
|
||||
|
||||
@@ -6,20 +6,6 @@ title: Стили
|
||||
|
||||
Раздел описывает правила написания CSS: PostCSS Modules, вложенность, медиа-запросы, переменные, форматирование.
|
||||
|
||||
## Приоритет стилизации
|
||||
|
||||
Приоритет инструментов стилизации (от высшего к низшему):
|
||||
|
||||
1. **Mantine-компоненты и их пропсы** — в первую очередь использовать встроенные возможности Mantine.
|
||||
2. **Глобальные CSS-токены** (`--color-*`, `--space-*`, `--radius-*`) — для значений, которые не покрываются Mantine.
|
||||
3. **PostCSS Module файлы** — когда Mantine не покрывает задачу и нужна кастомная стилизация.
|
||||
|
||||
- Инлайн-стили в компонентах запрещены.
|
||||
- Произвольные магические значения цветов, отступов и скруглений запрещены — использовать токены.
|
||||
- Глобальные стили вне `app/styles/` запрещены.
|
||||
|
||||
Подробный порядок действий — в разделе «Workflow».
|
||||
|
||||
## Общие правила
|
||||
|
||||
- Только **PostCSS** и **CSS Modules** для кастомной стилизации.
|
||||
|
||||
@@ -1,55 +1,27 @@
|
||||
---
|
||||
title: Шаблоны генерации кода
|
||||
title: Шаблоны и генерация кода
|
||||
---
|
||||
|
||||
# Шаблоны генерации кода
|
||||
<!-- @formatter:off -->
|
||||
::: v-pre
|
||||
|
||||
Раздел описывает инструменты, синтаксис шаблонов и примеры. Порядок действий при создании модулей и перечень обязательных шаблонов — в разделе «Workflow».
|
||||
# Шаблоны и генерация кода
|
||||
|
||||
## Обязательность
|
||||
Как работают шаблоны, как их создавать, синтаксис переменных и как генерировать код с помощью расширения VS Code и CLI.
|
||||
|
||||
- Создание типовых модулей — **только через шаблоны**. Ручное создание файловой структуры модуля запрещено, если для него существует шаблон.
|
||||
- Перед созданием нового модуля — проверить наличие подходящего шаблона в `.templates/`.
|
||||
- Если подходящего шаблона нет — сначала создать шаблон, затем использовать его.
|
||||
## Структура шаблонов
|
||||
|
||||
## Что генерируем
|
||||
|
||||
- Компоненты (`screens`, `layouts`, `widgets`, `features`, `entities`).
|
||||
- Страницы (nextjs `app`, `pages`).
|
||||
- Типовые инфраструктурные модули (например, `store`).
|
||||
|
||||
## Чем генерируем
|
||||
|
||||
### VSCode extension
|
||||
|
||||
[расширение VS Code](https://open-vsx.org/extension/MyTemplateGenerator/mytemplategenerator) — создание файлов и папок из шаблонов через UI‑интерфейс внутри редактора.
|
||||
|
||||
### CLI (для агентов)
|
||||
|
||||
[@gromlab/create](https://gromlab.ru/gromov/create) — CLI для генерации файлов и папок по шаблонам.
|
||||
|
||||
Примеры:
|
||||
```bash
|
||||
# Создать компонент
|
||||
create component button
|
||||
|
||||
# Создать компонент используя NPX
|
||||
npx @gromlab/create component button
|
||||
```
|
||||
|
||||
## Структура папок
|
||||
Все шаблоны лежат в `.templates/` в корне проекта.
|
||||
Каждая папка в `.templates/` — это уникальный шаблон.
|
||||
Все шаблоны лежат в `.templates/` в корне проекта. Каждая папка — отдельный шаблон.
|
||||
|
||||
```text
|
||||
.templates/ # корневая папка всех шаблонов
|
||||
.templates/
|
||||
├── component/ # шаблон компонента
|
||||
│ └── {{name.kebabCase}}/
|
||||
│ ├── styles/
|
||||
│ │ └── {{name.kebabCase}}.module.css
|
||||
│ ├── types/
|
||||
│ │ └── {{name.kebabCase}}.interface.ts
|
||||
│ ├── {{name.kebabCase}}.ui.tsx
|
||||
│ ├── {{name.kebabCase}}.tsx
|
||||
│ └── index.ts
|
||||
└── store/ # шаблон Zustand стора
|
||||
└── {{name.kebabCase}}/
|
||||
@@ -58,47 +30,59 @@ npx @gromlab/create component button
|
||||
└── index.ts
|
||||
```
|
||||
|
||||
## Синтаксис
|
||||
## Синтаксис шаблонов
|
||||
|
||||
- Переменные в шаблонах работают в именах файлов/папок и внутри файлов.
|
||||
- Базовая переменная — `name`.
|
||||
|
||||
Формат записи переменной:
|
||||
Переменные работают в именах файлов/папок и внутри файлов. Базовая переменная — `name`.
|
||||
|
||||
```text
|
||||
{{variable}}
|
||||
```
|
||||
|
||||
Модификаторы — это преобразования переменной, которые меняют регистр и формат записи. Они пишутся после имени через точку и применяются в момент генерации.
|
||||
Модификаторы меняют регистр и формат записи:
|
||||
|
||||
```text
|
||||
{{name.pascalCase}} -> MyButton
|
||||
{{name.camelCase}} -> myButton
|
||||
{{name.kebabCase}} -> my-button
|
||||
{{name.snakeCase}} -> my_button
|
||||
{{name.screamingSnakeCase}} -> MY_BUTTON
|
||||
{{name.pascalCase}} → MyButton
|
||||
{{name.camelCase}} → myButton
|
||||
{{name.kebabCase}} → my-button
|
||||
{{name.snakeCase}} → my_button
|
||||
{{name.screamingSnakeCase}} → MY_BUTTON
|
||||
```
|
||||
|
||||
Пример использования в шаблоне:
|
||||
## Как создать новый шаблон
|
||||
|
||||
1. Создать папку в `.templates/` с именем шаблона (например `hook`).
|
||||
2. Внутри разместить файлы и папки, используя `{{name}}` и модификаторы в именах и содержимом.
|
||||
3. Шаблон сразу доступен и в расширении VS Code, и в CLI.
|
||||
|
||||
Пример — создание шаблона для хука:
|
||||
|
||||
```text
|
||||
{{name}}.tsx
|
||||
{{name.pascalCase}}.tsx
|
||||
.templates/
|
||||
└── hook/
|
||||
└── {{name.kebabCase}}/
|
||||
├── {{name.kebabCase}}.hook.ts
|
||||
└── index.ts
|
||||
```
|
||||
|
||||
```tsx
|
||||
export const {{name.pascalCase}} = () => {
|
||||
return <div>{{name}}</div>
|
||||
```ts
|
||||
// .templates/hook/{{name.kebabCase}}.hook.ts
|
||||
export const {{name.camelCase}} = () => {
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
## Шаблон компонента
|
||||
```ts
|
||||
// .templates/hook/index.ts
|
||||
export { {{name.camelCase}} } from './{{name.kebabCase}}.hook'
|
||||
```
|
||||
|
||||
Структура компонента по шаблону. Создаётся генератором автоматически.
|
||||
## Примеры шаблонов
|
||||
|
||||
### Шаблон компонента
|
||||
|
||||
```ts
|
||||
// .templates/component/index.ts
|
||||
export { {{name.pascalCase}} } from './{{name.kebabCase}}.ui'
|
||||
export { {{name.pascalCase}} } from './{{name.kebabCase}}'
|
||||
```
|
||||
|
||||
```ts
|
||||
@@ -112,7 +96,7 @@ export interface {{name.pascalCase}}Props extends HTMLAttributes<HTMLDivElement>
|
||||
```
|
||||
|
||||
```tsx
|
||||
// .templates/component/{{name.kebabCase}}.ui.tsx
|
||||
// .templates/component/{{name.kebabCase}}.tsx
|
||||
import type { FC } from 'react'
|
||||
import cl from 'clsx'
|
||||
import type { {{name.pascalCase}}Props } from './types/{{name.kebabCase}}.interface'
|
||||
@@ -136,3 +120,31 @@ export const {{name.pascalCase}}: FC<{{name.pascalCase}}Props> = ({ className, .
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
## Генерация через VS Code
|
||||
|
||||
[MyTemplateGenerator](https://open-vsx.org/extension/MyTemplateGenerator/mytemplategenerator) — расширение для генерации файлов и папок из шаблонов через интерфейс редактора.
|
||||
|
||||
1. ПКМ на целевой папке в проводнике VS Code.
|
||||
2. **Generate from template** → выбрать шаблон.
|
||||
3. Ввести имя (например `button`) — расширение подставит его во все переменные `{{name}}`.
|
||||
|
||||
## Генерация через CLI
|
||||
|
||||
[@gromlab/create](https://www.npmjs.com/package/@gromlab/create) — CLI для генерации из тех же шаблонов. Используется через npx, глобальная установка не требуется.
|
||||
|
||||
```bash
|
||||
npx @gromlab/create <шаблон> <имя> <путь>
|
||||
```
|
||||
|
||||
| Команда | Что создаёт |
|
||||
|---|---|
|
||||
| `npx @gromlab/create component button src/shared/ui` | Компонент |
|
||||
| `npx @gromlab/create feature auth src/features` | Фичу |
|
||||
| `npx @gromlab/create widget header src/widgets` | Виджет |
|
||||
| `npx @gromlab/create entity user src/entities` | Сущность |
|
||||
| `npx @gromlab/create layout admin src/layouts` | Layout |
|
||||
| `npx @gromlab/create store auth src/shared/model` | Стор |
|
||||
|
||||
:::
|
||||
|
||||
|
||||
87
docs/ru/applied/vscode.md
Normal file
87
docs/ru/applied/vscode.md
Normal file
@@ -0,0 +1,87 @@
|
||||
---
|
||||
title: Настройка VS Code
|
||||
---
|
||||
|
||||
# Настройка 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": {
|
||||
"quickfix.biome": "explicit",
|
||||
"source.organizeImports.biome": "explicit"
|
||||
},
|
||||
"files.associations": {
|
||||
"*.css": "postcss"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Разбор настроек
|
||||
|
||||
| Настройка | Значение | Что делает |
|
||||
|---|---|---|
|
||||
| `editor.defaultFormatter` | `biomejs.biome` | Biome используется как единственный форматтер для всех файлов |
|
||||
| `editor.formatOnSave` | `true` | Код автоматически форматируется при каждом сохранении |
|
||||
| `codeActionsOnSave.quickfix.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` с общими для команды настройками.
|
||||
Reference in New Issue
Block a user