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:
12
.vitepress/cache/deps/_metadata.json
vendored
12
.vitepress/cache/deps/_metadata.json
vendored
@@ -1,25 +1,25 @@
|
|||||||
{
|
{
|
||||||
"hash": "a12e5463",
|
"hash": "e66d10e4",
|
||||||
"configHash": "dd9ed373",
|
"configHash": "bca2cdcc",
|
||||||
"lockfileHash": "5778a81f",
|
"lockfileHash": "5778a81f",
|
||||||
"browserHash": "2debf0f0",
|
"browserHash": "5fea5472",
|
||||||
"optimized": {
|
"optimized": {
|
||||||
"vue": {
|
"vue": {
|
||||||
"src": "../../../node_modules/vue/dist/vue.runtime.esm-bundler.js",
|
"src": "../../../node_modules/vue/dist/vue.runtime.esm-bundler.js",
|
||||||
"file": "vue.js",
|
"file": "vue.js",
|
||||||
"fileHash": "50b34fbf",
|
"fileHash": "cabb4131",
|
||||||
"needsInterop": false
|
"needsInterop": false
|
||||||
},
|
},
|
||||||
"vitepress > @vue/devtools-api": {
|
"vitepress > @vue/devtools-api": {
|
||||||
"src": "../../../node_modules/@vue/devtools-api/dist/index.js",
|
"src": "../../../node_modules/@vue/devtools-api/dist/index.js",
|
||||||
"file": "vitepress___@vue_devtools-api.js",
|
"file": "vitepress___@vue_devtools-api.js",
|
||||||
"fileHash": "ea163609",
|
"fileHash": "66e76a7b",
|
||||||
"needsInterop": false
|
"needsInterop": false
|
||||||
},
|
},
|
||||||
"vitepress > @vueuse/core": {
|
"vitepress > @vueuse/core": {
|
||||||
"src": "../../../node_modules/@vueuse/core/index.mjs",
|
"src": "../../../node_modules/@vueuse/core/index.mjs",
|
||||||
"file": "vitepress___@vueuse_core.js",
|
"file": "vitepress___@vueuse_core.js",
|
||||||
"fileHash": "2ef97fe2",
|
"fileHash": "6d04ab1e",
|
||||||
"needsInterop": false
|
"needsInterop": false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -5,11 +5,12 @@ const ruSidebar = [
|
|||||||
text: 'Workflow',
|
text: 'Workflow',
|
||||||
items: [
|
items: [
|
||||||
{ text: 'Начало работы', link: '/workflow/getting-started' },
|
{ text: 'Начало работы', link: '/workflow/getting-started' },
|
||||||
{ text: 'Создание приложения', link: '/workflow/creating-app' },
|
{ text: 'Создание проекта', link: '/workflow/creating-app' },
|
||||||
{ text: 'Создание страниц', link: '/workflow/creating-pages' },
|
{ text: 'Генерация кода', link: '/workflow/code-generation' },
|
||||||
{ text: 'Создание компонентов', link: '/workflow/creating-components' },
|
{ text: 'Добавление страницы', link: '/workflow/creating-pages' },
|
||||||
|
{ text: 'Добавление UI-модуля', link: '/workflow/creating-components' },
|
||||||
{ text: 'Стилизация', link: '/workflow/styling' },
|
{ text: 'Стилизация', link: '/workflow/styling' },
|
||||||
{ text: 'Работа с данными', link: '/workflow/data-fetching' },
|
{ text: 'Получение данных', link: '/workflow/data-fetching' },
|
||||||
{ text: 'Управление состоянием', link: '/workflow/state-management' },
|
{ text: 'Управление состоянием', link: '/workflow/state-management' },
|
||||||
{ text: 'Локализация', link: '/workflow/localization' },
|
{ text: 'Локализация', link: '/workflow/localization' },
|
||||||
],
|
],
|
||||||
@@ -28,8 +29,10 @@ const ruSidebar = [
|
|||||||
{
|
{
|
||||||
text: 'Прикладные разделы',
|
text: 'Прикладные разделы',
|
||||||
items: [
|
items: [
|
||||||
|
{ text: 'Настройка VS Code', link: '/applied/vscode' },
|
||||||
{ text: 'Структура проекта', link: '/applied/project-structure' },
|
{ text: 'Структура проекта', link: '/applied/project-structure' },
|
||||||
{ text: 'Компоненты', link: '/applied/components' },
|
{ text: 'Компоненты', link: '/applied/components' },
|
||||||
|
{ text: 'Page-level компоненты', link: '/applied/page-level' },
|
||||||
{ text: 'Шаблоны и генерация кода', link: '/applied/templates-generation' },
|
{ text: 'Шаблоны и генерация кода', link: '/applied/templates-generation' },
|
||||||
{ text: 'Стили', link: '/applied/styles' },
|
{ text: 'Стили', link: '/applied/styles' },
|
||||||
{ text: 'Изображения', link: '/applied/images-sprites' },
|
{ text: 'Изображения', link: '/applied/images-sprites' },
|
||||||
@@ -72,8 +75,10 @@ const enSidebar = [
|
|||||||
{
|
{
|
||||||
text: 'Applied Sections',
|
text: 'Applied Sections',
|
||||||
items: [
|
items: [
|
||||||
|
{ text: 'VS Code Setup', link: '/en/applied/vscode' },
|
||||||
{ text: 'Project Structure', link: '/en/applied/project-structure' },
|
{ text: 'Project Structure', link: '/en/applied/project-structure' },
|
||||||
{ text: 'Components', link: '/en/applied/components' },
|
{ text: 'Components', link: '/en/applied/components' },
|
||||||
|
{ text: 'Page-level Components', link: '/en/applied/page-level' },
|
||||||
{ text: 'Templates & Code Generation', link: '/en/applied/templates-generation' },
|
{ text: 'Templates & Code Generation', link: '/en/applied/templates-generation' },
|
||||||
{ text: 'Styles', link: '/en/applied/styles' },
|
{ text: 'Styles', link: '/en/applied/styles' },
|
||||||
{ text: 'Images', link: '/en/applied/images-sprites' },
|
{ text: 'Images', link: '/en/applied/images-sprites' },
|
||||||
|
|||||||
32
AGENTS.md
Normal file
32
AGENTS.md
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
# NextJS Style Guide — правила для агентов
|
||||||
|
|
||||||
|
Это проект документации (VitePress). Агент является основным писателем контента в этом проекте — записывает, оформляет и редактирует материал по указаниям пользователя.
|
||||||
|
|
||||||
|
## Документация
|
||||||
|
|
||||||
|
### Tip-блоки со ссылками
|
||||||
|
При создании или редактировании документации добавлять tip-блоки (`::: tip`)
|
||||||
|
с ссылками на связанные разделы, где можно найти развёрнутое описание
|
||||||
|
процесса, действия или настройки.
|
||||||
|
|
||||||
|
Формат:
|
||||||
|
```
|
||||||
|
::: tip Заголовок блока
|
||||||
|
Описание — [Название раздела](/путь).
|
||||||
|
:::
|
||||||
|
```
|
||||||
|
|
||||||
|
Заголовок обязателен — он должен кратко описывать о чём блок.
|
||||||
|
Описание должно объяснять что найдёт читатель по ссылке.
|
||||||
|
|
||||||
|
### Структура разделов
|
||||||
|
- **Workflow** — порядок действий ("что делать и в каком порядке")
|
||||||
|
- **Базовые правила** — стандарты и конвенции ("каким должен быть код")
|
||||||
|
- **Прикладные разделы** — конфигурация и устройство конкретной области ("как это настроить и использовать")
|
||||||
|
|
||||||
|
Не дублировать информацию между разделами — использовать ссылки.
|
||||||
|
|
||||||
|
### Единообразие
|
||||||
|
- Заголовок страницы (h1) совпадает с названием в sidebar.
|
||||||
|
- Описание раздела (текст после h1) раскрывает смысл через "Как...".
|
||||||
|
- Не описывать инструменты генерации в каждом разделе — ссылаться на прикладной раздел "Шаблоны и генерация кода".
|
||||||
@@ -40,6 +40,7 @@ Rules and standards for NextJS and TypeScript development: architecture, typing,
|
|||||||
|---------|---------------------|
|
|---------|---------------------|
|
||||||
| Project Structure | How are folders and files organized by FSD? |
|
| Project Structure | How are folders and files organized by FSD? |
|
||||||
| Components | How is a component structured: files, props, clsx, FC? |
|
| Components | How is a component structured: files, props, clsx, FC? |
|
||||||
|
| Page-level Components | How to define layout, page, loading, error, not-found? |
|
||||||
| Templates & Code Generation | How do templates work: syntax, variables, modifiers? |
|
| Templates & Code Generation | How do templates work: syntax, variables, modifiers? |
|
||||||
| Styles | How to write CSS: PostCSS Modules, nesting, media, tokens? |
|
| Styles | How to write CSS: PostCSS Modules, nesting, media, tokens? |
|
||||||
| Images | _(not filled)_ |
|
| Images | _(not filled)_ |
|
||||||
|
|||||||
27
README_RU.md
27
README_RU.md
@@ -4,24 +4,25 @@
|
|||||||
|
|
||||||
## Для ассистентов
|
## Для ассистентов
|
||||||
|
|
||||||
Полная документация в одном MD файле: https://gromlab.ru/docs/frontend-style-guide/raw/branch/main/generated/ru/RULES.md
|
Полная документация в одном MD файле: https://gromlab.ru/docs/nextjs-style-guide/raw/branch/main/generated/ru/RULES.md
|
||||||
|
|
||||||
## Структура документации
|
## Структура документации
|
||||||
|
|
||||||
### Workflow
|
### Workflow
|
||||||
|
|
||||||
**Что делать** в конкретной ситуации — пошаговые инструкции.
|
**Что делать и в каком порядке** — пошаговые инструкции.
|
||||||
|
|
||||||
| Раздел | Отвечает на вопрос |
|
| Раздел | Отвечает на вопрос |
|
||||||
|--------|-------------------|
|
|--------|-------------------|
|
||||||
| Начало работы | Какие инструменты установить перед началом разработки? |
|
| Начало работы | Что нужно знать перед началом разработки? |
|
||||||
| Создание приложения | Как создать новый проект, откуда взять шаблон? |
|
| Создание проекта | Как начать новый проект? |
|
||||||
| Создание страниц | Как добавить страницу: роутинг и экран? |
|
| Генерация кода | Какие модули должны генерироваться из шаблонов? |
|
||||||
| Создание компонентов | Как генерировать компоненты через шаблоны? |
|
| Добавление страницы | Как добавить новую страницу в проект? |
|
||||||
| Стилизация | Чем стилизовать: Mantine, токены или PostCSS? |
|
| Добавление UI-модуля | Как создать компонент, фичу, виджет, сущность или layout? |
|
||||||
| Работа с данными | Как получать данные: SWR, кодген, сокеты? |
|
| Стилизация | Как стилизовать компоненты в проекте? |
|
||||||
| Управление состоянием | Когда и как создавать стор (Zustand)? |
|
| Получение данных | Как получать данные с сервера? |
|
||||||
| Локализация | Как добавлять переводы и работать с i18next? |
|
| Управление состоянием | Как работать с состоянием? |
|
||||||
|
| Локализация | Как добавлять переводы и подключать локализацию? |
|
||||||
|
|
||||||
### Базовые правила
|
### Базовые правила
|
||||||
|
|
||||||
@@ -38,13 +39,15 @@
|
|||||||
|
|
||||||
### Прикладные разделы
|
### Прикладные разделы
|
||||||
|
|
||||||
**Как устроена конкретная область** — правила, структура и примеры кода для отдельных технологий и инструментов.
|
**Как это настроить и использовать** — конфигурация, структура и примеры кода для конкретных областей.
|
||||||
|
|
||||||
| Раздел | Отвечает на вопрос |
|
| Раздел | Отвечает на вопрос |
|
||||||
|--------|-------------------|
|
|--------|-------------------|
|
||||||
|
| Настройка VS Code | Как настроить редактор для проекта? |
|
||||||
| Структура проекта | Как организованы папки и файлы по FSD? |
|
| Структура проекта | Как организованы папки и файлы по FSD? |
|
||||||
| Компоненты | Как устроен компонент: файлы, пропсы, clsx, FC? |
|
| Компоненты | Как устроен компонент: файлы, пропсы, clsx, FC? |
|
||||||
| Шаблоны и генерация | Как работают шаблоны: синтаксис, переменные, модификаторы? |
|
| Page-level компоненты | Как описывать layout, page, loading, error, not-found? |
|
||||||
|
| Шаблоны и генерация кода | Как работают шаблоны, синтаксис и инструменты генерации? |
|
||||||
| Стили | Как писать CSS: PostCSS Modules, вложенность, медиа, токены? |
|
| Стили | Как писать CSS: PostCSS Modules, вложенность, медиа, токены? |
|
||||||
| Изображения | _(не заполнен)_ |
|
| Изображения | _(не заполнен)_ |
|
||||||
| SVG-спрайты | _(не заполнен)_ |
|
| SVG-спрайты | _(не заполнен)_ |
|
||||||
|
|||||||
57
concat-md.js
57
concat-md.js
@@ -1,4 +1,3 @@
|
|||||||
import { concatMdSync } from "concat-md";
|
|
||||||
import path from "path";
|
import path from "path";
|
||||||
import fs from "fs";
|
import fs from "fs";
|
||||||
|
|
||||||
@@ -9,6 +8,7 @@ const fileOrder = [
|
|||||||
// workflow
|
// workflow
|
||||||
"workflow/getting-started.md",
|
"workflow/getting-started.md",
|
||||||
"workflow/creating-app.md",
|
"workflow/creating-app.md",
|
||||||
|
"workflow/code-generation.md",
|
||||||
"workflow/creating-pages.md",
|
"workflow/creating-pages.md",
|
||||||
"workflow/creating-components.md",
|
"workflow/creating-components.md",
|
||||||
"workflow/styling.md",
|
"workflow/styling.md",
|
||||||
@@ -23,8 +23,10 @@ const fileOrder = [
|
|||||||
"basics/documentation.md",
|
"basics/documentation.md",
|
||||||
"basics/typing.md",
|
"basics/typing.md",
|
||||||
// applied
|
// applied
|
||||||
|
"applied/vscode.md",
|
||||||
"applied/project-structure.md",
|
"applied/project-structure.md",
|
||||||
"applied/components.md",
|
"applied/components.md",
|
||||||
|
"applied/page-level.md",
|
||||||
"applied/templates-generation.md",
|
"applied/templates-generation.md",
|
||||||
"applied/styles.md",
|
"applied/styles.md",
|
||||||
"applied/images-sprites.md",
|
"applied/images-sprites.md",
|
||||||
@@ -37,6 +39,27 @@ const fileOrder = [
|
|||||||
"applied/localization.md",
|
"applied/localization.md",
|
||||||
];
|
];
|
||||||
|
|
||||||
|
// Удалить frontmatter из содержимого md-файла
|
||||||
|
const stripFrontmatter = (content) =>
|
||||||
|
content.replace(/^---[\s\S]*?---\n*/m, "");
|
||||||
|
|
||||||
|
// Сдвинуть уровень заголовков на 1 вниз (h1→h2, h2→h3, ...)
|
||||||
|
// Не трогает заголовки внутри блоков кода
|
||||||
|
const shiftHeadings = (content) => {
|
||||||
|
const lines = content.split("\n");
|
||||||
|
let inCodeBlock = false;
|
||||||
|
|
||||||
|
return lines
|
||||||
|
.map((line) => {
|
||||||
|
if (line.startsWith("```")) inCodeBlock = !inCodeBlock;
|
||||||
|
if (inCodeBlock) return line;
|
||||||
|
if (/^#{1,5}\s/.test(line)) return "#" + line;
|
||||||
|
return line;
|
||||||
|
})
|
||||||
|
.join("\n");
|
||||||
|
};
|
||||||
|
|
||||||
|
// Собрать RULES.md с мета-якорями для каждого файла
|
||||||
const buildRules = (lang) => {
|
const buildRules = (lang) => {
|
||||||
const srcDir = `./docs/${lang}`;
|
const srcDir = `./docs/${lang}`;
|
||||||
const outDir = `./generated/${lang}`;
|
const outDir = `./generated/${lang}`;
|
||||||
@@ -49,18 +72,24 @@ const buildRules = (lang) => {
|
|||||||
|
|
||||||
fs.mkdirSync(outDir, { recursive: true });
|
fs.mkdirSync(outDir, { recursive: true });
|
||||||
|
|
||||||
const resultMd = concatMdSync(srcDir, {
|
const parts = [];
|
||||||
toc: false,
|
|
||||||
sorter: (a, b) => {
|
|
||||||
const indexA = fileOrder.indexOf(a);
|
|
||||||
const indexB = fileOrder.indexOf(b);
|
|
||||||
const posA = indexA === -1 ? fileOrder.length : indexA;
|
|
||||||
const posB = indexB === -1 ? fileOrder.length : indexB;
|
|
||||||
return posA - posB;
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
fs.writeFileSync(outFile, resultMd, "utf8");
|
for (const file of fileOrder) {
|
||||||
|
const filePath = path.join(srcDir, file);
|
||||||
|
if (!fs.existsSync(filePath)) continue;
|
||||||
|
|
||||||
|
const raw = fs.readFileSync(filePath, "utf8");
|
||||||
|
const content = stripFrontmatter(raw).trim();
|
||||||
|
if (!content) continue;
|
||||||
|
|
||||||
|
// Мета-якорь: путь VitePress без расширения
|
||||||
|
const route = "/" + file.replace(/\.md$/, "");
|
||||||
|
// index.md остаётся без сдвига (его h1 — главный заголовок документа)
|
||||||
|
const processed = file === "index.md" ? content : shiftHeadings(content);
|
||||||
|
parts.push(`<!-- ${route} -->\n${processed}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
fs.writeFileSync(outFile, parts.join("\n\n"), "utf8");
|
||||||
console.log(`RULES.md (${lang}) создан: ${outFile}`);
|
console.log(`RULES.md (${lang}) создан: ${outFile}`);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -77,9 +106,7 @@ const buildReadme = (lang, outFile) => {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const content = fs.readFileSync(indexPath, "utf8")
|
const content = stripFrontmatter(fs.readFileSync(indexPath, "utf8"));
|
||||||
.replace(/^---[\s\S]*?---\n*/m, "");
|
|
||||||
|
|
||||||
fs.writeFileSync(outFile, content, "utf8");
|
fs.writeFileSync(outFile, content, "utf8");
|
||||||
console.log(`${outFile} создан из ${indexPath}`);
|
console.log(`${outFile} создан из ${indexPath}`);
|
||||||
};
|
};
|
||||||
|
|||||||
7
docs/en/applied/page-level.md
Normal file
7
docs/en/applied/page-level.md
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
---
|
||||||
|
title: Page-level Components
|
||||||
|
---
|
||||||
|
|
||||||
|
# Page-level Components
|
||||||
|
|
||||||
|
Next.js App Router special files used by the framework by convention: `layout.tsx`, `page.tsx`, `loading.tsx`, `error.tsx`, `not-found.tsx`, `template.tsx`.
|
||||||
@@ -40,6 +40,7 @@ Rules and standards for NextJS and TypeScript development: architecture, typing,
|
|||||||
|---------|---------------------|
|
|---------|---------------------|
|
||||||
| Project Structure | How are folders and files organized by FSD? |
|
| Project Structure | How are folders and files organized by FSD? |
|
||||||
| Components | How is a component structured: files, props, clsx, FC? |
|
| Components | How is a component structured: files, props, clsx, FC? |
|
||||||
|
| Page-level Components | How to define layout, page, loading, error, not-found? |
|
||||||
| Templates & Code Generation | How do templates work: syntax, variables, modifiers? |
|
| Templates & Code Generation | How do templates work: syntax, variables, modifiers? |
|
||||||
| Styles | How to write CSS: PostCSS Modules, nesting, media, tokens? |
|
| Styles | How to write CSS: PostCSS Modules, nesting, media, tokens? |
|
||||||
| Images | _(not filled)_ |
|
| Images | _(not filled)_ |
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ container/
|
|||||||
│ └── container.module.scss
|
│ └── container.module.scss
|
||||||
├── types/
|
├── types/
|
||||||
│ └── container.interface.ts
|
│ └── container.interface.ts
|
||||||
├── container.ui.tsx
|
├── container.tsx
|
||||||
└── index.ts
|
└── index.ts
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -39,7 +39,7 @@ export interface ContainerProps extends HTMLAttributes<HTMLDivElement> {}
|
|||||||
```
|
```
|
||||||
Интерфес параметров компонента всегда наследует свойства своего тега: div, button, итд..
|
Интерфес параметров компонента всегда наследует свойства своего тега: div, button, итд..
|
||||||
|
|
||||||
`container.ui.tsx`
|
`container.tsx`
|
||||||
|
|
||||||
```tsx
|
```tsx
|
||||||
import type { FC } from 'react'
|
import type { FC } from 'react'
|
||||||
@@ -73,7 +73,7 @@ export const Container: FC<ContainerProps> = ({ className, ...htmlAttr }) => {
|
|||||||
`index.ts`
|
`index.ts`
|
||||||
|
|
||||||
```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
|
```text
|
||||||
src/
|
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-компоненты страниц
|
├── screens/ # UI-компоненты страниц
|
||||||
|
│ ├── home/
|
||||||
|
│ │ ├── home.screen.tsx
|
||||||
|
│ │ └── index.ts
|
||||||
│ └── profile/
|
│ └── profile/
|
||||||
│ ├── profile.screen.tsx
|
│ ├── profile.screen.tsx
|
||||||
│ └── index.ts
|
│ └── index.ts
|
||||||
@@ -28,7 +37,7 @@ src/
|
|||||||
├── features/ # Пользовательские сценарии
|
├── features/ # Пользовательские сценарии
|
||||||
│ └── auth-by-email/
|
│ └── auth-by-email/
|
||||||
│ ├── ui/
|
│ ├── ui/
|
||||||
│ │ └── login-form.ui.tsx
|
│ │ └── login-form.tsx
|
||||||
│ ├── model/
|
│ ├── model/
|
||||||
│ │ └── auth-by-email.store.ts
|
│ │ └── auth-by-email.store.ts
|
||||||
│ ├── auth-by-email.feature.tsx
|
│ ├── auth-by-email.feature.tsx
|
||||||
@@ -46,7 +55,7 @@ src/
|
|||||||
│ │ └── icon.module.css
|
│ │ └── icon.module.css
|
||||||
│ ├── types/
|
│ ├── types/
|
||||||
│ │ └── icon.interface.ts
|
│ │ └── icon.interface.ts
|
||||||
│ ├── icon.ui.tsx
|
│ ├── icon.tsx
|
||||||
│ └── index.ts
|
│ └── index.ts
|
||||||
├── lib/ # Утилиты и хелперы
|
├── lib/ # Утилиты и хелперы
|
||||||
├── services/ # Общие сервисы и клиенты
|
├── services/ # Общие сервисы и клиенты
|
||||||
@@ -58,61 +67,83 @@ src/
|
|||||||
└── video/
|
└── video/
|
||||||
```
|
```
|
||||||
|
|
||||||
## Слой app/
|
## Слой `app/`
|
||||||
|
|
||||||
Общее для обоих вариантов: провайдеры и глобальные стили. Различается только способ организации роутинга.
|
Папка `app/` совмещает две роли: инициализация приложения (провайдеры, глобальные стили) и файловый роутинг Next.js (route-сегменты, `layout.tsx`, `page.tsx`).
|
||||||
|
|
||||||
### React SPA
|
- `providers/` и `styles/` -- это инфраструктура приложения, они не являются частью роутинга.
|
||||||
|
- Route-сегменты (вложенные папки с `page.tsx`) -- это роутинг Next.js. Они не содержат логики, только импортируют экраны из `screens/`.
|
||||||
|
|
||||||
```text
|
Компоненты, хуки, стили и утилиты не размещаются внутри route-сегментов -- всё это живёт в соответствующих слоях FSD.
|
||||||
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
|
|
||||||
```
|
|
||||||
|
|
||||||
## Правила организации
|
## Правила организации
|
||||||
|
|
||||||
- В слоях 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-элементы/компоненты, которыми пользуются сразу несколько модулей; в этом случае они экспортируются наружу и не считаются «дочерними» для слоя.
|
- В `shared/ui/` хранятся базовые UI-элементы/компоненты, которыми пользуются сразу несколько модулей; в этом случае они экспортируются наружу и не считаются «дочерними» для слоя.
|
||||||
- Если модуль строится вокруг «главного» компонента (`*.feature.tsx`, `*.screen.tsx`, `*.widget.tsx`), помещайте его в корень модуля и экспортируйте через `index.ts`. Проверяйте, что `ui/` не используется просто как «контейнер» слоя.
|
- Если модуль строится вокруг «главного» компонента (`*.feature.tsx`, `*.screen.tsx`, `*.widget.tsx`), помещайте его в корень модуля и экспортируйте через `index.ts`. Проверяйте, что `ui/` не используется просто как «контейнер» слоя.
|
||||||
|
|
||||||
- Каждый слой и модуль хранится в собственной папке.
|
- Каждый слой и модуль хранится в собственной папке.
|
||||||
- Внутренние реализации разделяются на `ui/`, `model/`, `styles/`, `helpers/`, `lib/`, `api/`.
|
- Внутренние реализации разделяются на `ui/`, `model/`, `styles/`, `helpers/`, `lib/`, `api/`.
|
||||||
- Публичный API модуля объявляется в `index.ts`.
|
- Публичный 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, вложенность, медиа-запросы, переменные, форматирование.
|
Раздел описывает правила написания CSS: PostCSS Modules, вложенность, медиа-запросы, переменные, форматирование.
|
||||||
|
|
||||||
## Приоритет стилизации
|
|
||||||
|
|
||||||
Приоритет инструментов стилизации (от высшего к низшему):
|
|
||||||
|
|
||||||
1. **Mantine-компоненты и их пропсы** — в первую очередь использовать встроенные возможности Mantine.
|
|
||||||
2. **Глобальные CSS-токены** (`--color-*`, `--space-*`, `--radius-*`) — для значений, которые не покрываются Mantine.
|
|
||||||
3. **PostCSS Module файлы** — когда Mantine не покрывает задачу и нужна кастомная стилизация.
|
|
||||||
|
|
||||||
- Инлайн-стили в компонентах запрещены.
|
|
||||||
- Произвольные магические значения цветов, отступов и скруглений запрещены — использовать токены.
|
|
||||||
- Глобальные стили вне `app/styles/` запрещены.
|
|
||||||
|
|
||||||
Подробный порядок действий — в разделе «Workflow».
|
|
||||||
|
|
||||||
## Общие правила
|
## Общие правила
|
||||||
|
|
||||||
- Только **PostCSS** и **CSS Modules** для кастомной стилизации.
|
- Только **PostCSS** и **CSS Modules** для кастомной стилизации.
|
||||||
|
|||||||
@@ -1,55 +1,27 @@
|
|||||||
---
|
---
|
||||||
title: Шаблоны генерации кода
|
title: Шаблоны и генерация кода
|
||||||
---
|
---
|
||||||
|
|
||||||
# Шаблоны генерации кода
|
<!-- @formatter:off -->
|
||||||
|
::: v-pre
|
||||||
|
|
||||||
Раздел описывает инструменты, синтаксис шаблонов и примеры. Порядок действий при создании модулей и перечень обязательных шаблонов — в разделе «Workflow».
|
# Шаблоны и генерация кода
|
||||||
|
|
||||||
## Обязательность
|
Как работают шаблоны, как их создавать, синтаксис переменных и как генерировать код с помощью расширения VS Code и CLI.
|
||||||
|
|
||||||
- Создание типовых модулей — **только через шаблоны**. Ручное создание файловой структуры модуля запрещено, если для него существует шаблон.
|
## Структура шаблонов
|
||||||
- Перед созданием нового модуля — проверить наличие подходящего шаблона в `.templates/`.
|
|
||||||
- Если подходящего шаблона нет — сначала создать шаблон, затем использовать его.
|
|
||||||
|
|
||||||
## Что генерируем
|
Все шаблоны лежат в `.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/` — это уникальный шаблон.
|
|
||||||
|
|
||||||
```text
|
```text
|
||||||
.templates/ # корневая папка всех шаблонов
|
.templates/
|
||||||
├── component/ # шаблон компонента
|
├── component/ # шаблон компонента
|
||||||
│ └── {{name.kebabCase}}/
|
│ └── {{name.kebabCase}}/
|
||||||
│ ├── styles/
|
│ ├── styles/
|
||||||
│ │ └── {{name.kebabCase}}.module.css
|
│ │ └── {{name.kebabCase}}.module.css
|
||||||
│ ├── types/
|
│ ├── types/
|
||||||
│ │ └── {{name.kebabCase}}.interface.ts
|
│ │ └── {{name.kebabCase}}.interface.ts
|
||||||
│ ├── {{name.kebabCase}}.ui.tsx
|
│ ├── {{name.kebabCase}}.tsx
|
||||||
│ └── index.ts
|
│ └── index.ts
|
||||||
└── store/ # шаблон Zustand стора
|
└── store/ # шаблон Zustand стора
|
||||||
└── {{name.kebabCase}}/
|
└── {{name.kebabCase}}/
|
||||||
@@ -58,47 +30,59 @@ npx @gromlab/create component button
|
|||||||
└── index.ts
|
└── index.ts
|
||||||
```
|
```
|
||||||
|
|
||||||
## Синтаксис
|
## Синтаксис шаблонов
|
||||||
|
|
||||||
- Переменные в шаблонах работают в именах файлов/папок и внутри файлов.
|
Переменные работают в именах файлов/папок и внутри файлов. Базовая переменная — `name`.
|
||||||
- Базовая переменная — `name`.
|
|
||||||
|
|
||||||
Формат записи переменной:
|
|
||||||
|
|
||||||
```text
|
```text
|
||||||
{{variable}}
|
{{variable}}
|
||||||
```
|
```
|
||||||
|
|
||||||
Модификаторы — это преобразования переменной, которые меняют регистр и формат записи. Они пишутся после имени через точку и применяются в момент генерации.
|
Модификаторы меняют регистр и формат записи:
|
||||||
|
|
||||||
```text
|
```text
|
||||||
{{name.pascalCase}} -> MyButton
|
{{name.pascalCase}} → MyButton
|
||||||
{{name.camelCase}} -> myButton
|
{{name.camelCase}} → myButton
|
||||||
{{name.kebabCase}} -> my-button
|
{{name.kebabCase}} → my-button
|
||||||
{{name.snakeCase}} -> my_button
|
{{name.snakeCase}} → my_button
|
||||||
{{name.screamingSnakeCase}} -> MY_BUTTON
|
{{name.screamingSnakeCase}} → MY_BUTTON
|
||||||
```
|
```
|
||||||
|
|
||||||
Пример использования в шаблоне:
|
## Как создать новый шаблон
|
||||||
|
|
||||||
|
1. Создать папку в `.templates/` с именем шаблона (например `hook`).
|
||||||
|
2. Внутри разместить файлы и папки, используя `{{name}}` и модификаторы в именах и содержимом.
|
||||||
|
3. Шаблон сразу доступен и в расширении VS Code, и в CLI.
|
||||||
|
|
||||||
|
Пример — создание шаблона для хука:
|
||||||
|
|
||||||
```text
|
```text
|
||||||
{{name}}.tsx
|
.templates/
|
||||||
{{name.pascalCase}}.tsx
|
└── hook/
|
||||||
|
└── {{name.kebabCase}}/
|
||||||
|
├── {{name.kebabCase}}.hook.ts
|
||||||
|
└── index.ts
|
||||||
```
|
```
|
||||||
|
|
||||||
```tsx
|
```ts
|
||||||
export const {{name.pascalCase}} = () => {
|
// .templates/hook/{{name.kebabCase}}.hook.ts
|
||||||
return <div>{{name}}</div>
|
export const {{name.camelCase}} = () => {
|
||||||
|
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
## Шаблон компонента
|
```ts
|
||||||
|
// .templates/hook/index.ts
|
||||||
|
export { {{name.camelCase}} } from './{{name.kebabCase}}.hook'
|
||||||
|
```
|
||||||
|
|
||||||
Структура компонента по шаблону. Создаётся генератором автоматически.
|
## Примеры шаблонов
|
||||||
|
|
||||||
|
### Шаблон компонента
|
||||||
|
|
||||||
```ts
|
```ts
|
||||||
// .templates/component/index.ts
|
// .templates/component/index.ts
|
||||||
export { {{name.pascalCase}} } from './{{name.kebabCase}}.ui'
|
export { {{name.pascalCase}} } from './{{name.kebabCase}}'
|
||||||
```
|
```
|
||||||
|
|
||||||
```ts
|
```ts
|
||||||
@@ -112,7 +96,7 @@ export interface {{name.pascalCase}}Props extends HTMLAttributes<HTMLDivElement>
|
|||||||
```
|
```
|
||||||
|
|
||||||
```tsx
|
```tsx
|
||||||
// .templates/component/{{name.kebabCase}}.ui.tsx
|
// .templates/component/{{name.kebabCase}}.tsx
|
||||||
import type { FC } from 'react'
|
import type { FC } from 'react'
|
||||||
import cl from 'clsx'
|
import cl from 'clsx'
|
||||||
import type { {{name.pascalCase}}Props } from './types/{{name.kebabCase}}.interface'
|
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` с общими для команды настройками.
|
||||||
@@ -34,7 +34,8 @@ title: Именование
|
|||||||
- `.widget.tsx` — виджет
|
- `.widget.tsx` — виджет
|
||||||
- `.feature.tsx` — UI фичи
|
- `.feature.tsx` — UI фичи
|
||||||
- `.entity.tsx` — UI сущности
|
- `.entity.tsx` — UI сущности
|
||||||
- `.ui.tsx` — UI‑компонент
|
|
||||||
|
Остальные `.tsx` файлы (компоненты в `shared/ui/`, дочерние компоненты в `ui/`) не помечаются суффиксами — расширение `.tsx` само по себе означает UI‑компонент.
|
||||||
|
|
||||||
**Логика и модель**
|
**Логика и модель**
|
||||||
- `.store.ts` — стор
|
- `.store.ts` — стор
|
||||||
@@ -69,7 +70,7 @@ src/
|
|||||||
├── features/
|
├── features/
|
||||||
│ └── auth-by-email/
|
│ └── auth-by-email/
|
||||||
│ ├── ui/
|
│ ├── ui/
|
||||||
│ │ └── login-form.ui.tsx
|
│ │ └── login-form.tsx
|
||||||
│ ├── auth-by-email.feature.tsx
|
│ ├── auth-by-email.feature.tsx
|
||||||
│ └── index.ts
|
│ └── index.ts
|
||||||
└── shared/
|
└── shared/
|
||||||
@@ -79,7 +80,7 @@ src/
|
|||||||
│ └── icon.module.css
|
│ └── icon.module.css
|
||||||
├── types/
|
├── types/
|
||||||
│ └── icon.interface.ts
|
│ └── icon.interface.ts
|
||||||
├── icon.ui.tsx
|
├── icon.tsx
|
||||||
└── index.ts
|
└── index.ts
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
@@ -4,24 +4,25 @@
|
|||||||
|
|
||||||
## Для ассистентов
|
## Для ассистентов
|
||||||
|
|
||||||
Полная документация в одном MD файле: https://gromlab.ru/docs/frontend-style-guide/raw/branch/main/generated/ru/RULES.md
|
Полная документация в одном MD файле: https://gromlab.ru/docs/nextjs-style-guide/raw/branch/main/generated/ru/RULES.md
|
||||||
|
|
||||||
## Структура документации
|
## Структура документации
|
||||||
|
|
||||||
### Workflow
|
### Workflow
|
||||||
|
|
||||||
**Что делать** в конкретной ситуации — пошаговые инструкции.
|
**Что делать и в каком порядке** — пошаговые инструкции.
|
||||||
|
|
||||||
| Раздел | Отвечает на вопрос |
|
| Раздел | Отвечает на вопрос |
|
||||||
|--------|-------------------|
|
|--------|-------------------|
|
||||||
| Начало работы | Какие инструменты установить перед началом разработки? |
|
| Начало работы | Что нужно знать перед началом разработки? |
|
||||||
| Создание приложения | Как создать новый проект, откуда взять шаблон? |
|
| Создание проекта | Как начать новый проект? |
|
||||||
| Создание страниц | Как добавить страницу: роутинг и экран? |
|
| Генерация кода | Какие модули должны генерироваться из шаблонов? |
|
||||||
| Создание компонентов | Как генерировать компоненты через шаблоны? |
|
| Добавление страницы | Как добавить новую страницу в проект? |
|
||||||
| Стилизация | Чем стилизовать: Mantine, токены или PostCSS? |
|
| Добавление UI-модуля | Как создать компонент, фичу, виджет, сущность или layout? |
|
||||||
| Работа с данными | Как получать данные: SWR, кодген, сокеты? |
|
| Стилизация | Как стилизовать компоненты в проекте? |
|
||||||
| Управление состоянием | Когда и как создавать стор (Zustand)? |
|
| Получение данных | Как получать данные с сервера? |
|
||||||
| Локализация | Как добавлять переводы и работать с i18next? |
|
| Управление состоянием | Как работать с состоянием? |
|
||||||
|
| Локализация | Как добавлять переводы и подключать локализацию? |
|
||||||
|
|
||||||
### Базовые правила
|
### Базовые правила
|
||||||
|
|
||||||
@@ -38,13 +39,15 @@
|
|||||||
|
|
||||||
### Прикладные разделы
|
### Прикладные разделы
|
||||||
|
|
||||||
**Как устроена конкретная область** — правила, структура и примеры кода для отдельных технологий и инструментов.
|
**Как это настроить и использовать** — конфигурация, структура и примеры кода для конкретных областей.
|
||||||
|
|
||||||
| Раздел | Отвечает на вопрос |
|
| Раздел | Отвечает на вопрос |
|
||||||
|--------|-------------------|
|
|--------|-------------------|
|
||||||
|
| Настройка VS Code | Как настроить редактор для проекта? |
|
||||||
| Структура проекта | Как организованы папки и файлы по FSD? |
|
| Структура проекта | Как организованы папки и файлы по FSD? |
|
||||||
| Компоненты | Как устроен компонент: файлы, пропсы, clsx, FC? |
|
| Компоненты | Как устроен компонент: файлы, пропсы, clsx, FC? |
|
||||||
| Шаблоны и генерация | Как работают шаблоны: синтаксис, переменные, модификаторы? |
|
| Page-level компоненты | Как описывать layout, page, loading, error, not-found? |
|
||||||
|
| Шаблоны и генерация кода | Как работают шаблоны, синтаксис и инструменты генерации? |
|
||||||
| Стили | Как писать CSS: PostCSS Modules, вложенность, медиа, токены? |
|
| Стили | Как писать CSS: PostCSS Modules, вложенность, медиа, токены? |
|
||||||
| Изображения | _(не заполнен)_ |
|
| Изображения | _(не заполнен)_ |
|
||||||
| SVG-спрайты | _(не заполнен)_ |
|
| SVG-спрайты | _(не заполнен)_ |
|
||||||
|
|||||||
32
docs/ru/workflow/code-generation.md
Normal file
32
docs/ru/workflow/code-generation.md
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
---
|
||||||
|
title: Генерация кода
|
||||||
|
---
|
||||||
|
|
||||||
|
# Генерация кода
|
||||||
|
|
||||||
|
Как создавать модули в проекте с помощью шаблонов — какие модули покрыты генерацией и когда стоит создавать новые шаблоны.
|
||||||
|
|
||||||
|
## Какие модули генерируются из шаблонов
|
||||||
|
|
||||||
|
| Модуль | Слой | Шаблон |
|
||||||
|
|---|---|---|
|
||||||
|
| Компонент | `shared/ui/` | `component` |
|
||||||
|
| Фича | `features/` | `feature` |
|
||||||
|
| Виджет | `widgets/` | `widget` |
|
||||||
|
| Сущность | `entities/` | `entity` |
|
||||||
|
| Layout | `layouts/` | `layout` |
|
||||||
|
| Экран | `screens/` | `screen` |
|
||||||
|
| Стор | `model/` | `store` |
|
||||||
|
|
||||||
|
## Что нужно знать
|
||||||
|
|
||||||
|
В проекте принято создавать модули из шаблонов `.templates/`. Шаблоны задают единообразную файловую структуру и сокращают рутину — не нужно вручную создавать папки, файлы типов, стилей и экспорты.
|
||||||
|
|
||||||
|
Если для нужного модуля нет подходящего шаблона — стоит сначала создать шаблон, а затем использовать его.
|
||||||
|
|
||||||
|
## Когда создавать новый шаблон
|
||||||
|
|
||||||
|
- Повторяющаяся структура появляется больше одного раза.
|
||||||
|
- Существующий шаблон не покрывает нужный тип модуля.
|
||||||
|
|
||||||
|
Инструменты и синтаксис шаблонов — [Шаблоны и генерация кода](/applied/templates-generation).
|
||||||
@@ -1,7 +1,31 @@
|
|||||||
---
|
---
|
||||||
title: Создание приложения
|
title: Создание проекта
|
||||||
---
|
---
|
||||||
|
|
||||||
# Создание приложения
|
# Создание проекта
|
||||||
|
|
||||||
Как создать новое приложение: выбор шаблона проекта и инициализация.
|
Как начать новый проект, соответствующий стандартам этого руководства.
|
||||||
|
|
||||||
|
## Что нужно знать
|
||||||
|
|
||||||
|
Новый проект создаётся из готового шаблона. Шаблон содержит настроенный стек, структуру FSD, конфигурацию редактора и шаблоны генерации кода — проект готов к разработке сразу после установки зависимостей.
|
||||||
|
|
||||||
|
### Создание из шаблона
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npx tiged git@gromlab.ru:templates/nextjs.git my-app
|
||||||
|
cd my-app
|
||||||
|
npm install
|
||||||
|
```
|
||||||
|
|
||||||
|
## Что входит в шаблон
|
||||||
|
|
||||||
|
- Next.js + TypeScript (App Router)
|
||||||
|
- Mantine UI + PostCSS Modules
|
||||||
|
- Biome (линтинг и форматирование)
|
||||||
|
- Zustand, SWR
|
||||||
|
- Структура FSD (`screens/`, `widgets/`, `features/`, `entities/`, `shared/`)
|
||||||
|
- Шаблоны генерации (`.templates/`)
|
||||||
|
- Конфигурация VS Code (`.vscode/`)
|
||||||
|
- CSS-токены (цвета, отступы, радиусы, медиа)
|
||||||
|
- Open Graph метаданные
|
||||||
|
|||||||
@@ -1,7 +1,22 @@
|
|||||||
---
|
---
|
||||||
title: Создание компонентов
|
title: Добавление UI-модуля
|
||||||
---
|
---
|
||||||
|
|
||||||
# Создание компонентов
|
# Добавление UI-модуля
|
||||||
|
|
||||||
Генерация компонентов через шаблоны, работа с дочерними компонентами.
|
Как создать компонент, фичу, виджет, сущность или layout в проекте.
|
||||||
|
|
||||||
|
## Что нужно знать
|
||||||
|
|
||||||
|
Все UI-модули создаются только из шаблонов `.templates/`. Ручное создание файловой структуры запрещено. Если подходящего шаблона нет — сначала создать шаблон в `.templates/`, затем использовать его.
|
||||||
|
|
||||||
|
## Порядок действий
|
||||||
|
|
||||||
|
1. [Сгенерировать](/applied/templates-generation) модуль из соответствующего шаблона в целевой слой.
|
||||||
|
2. Заполнить модуль логикой и стилями.
|
||||||
|
|
||||||
|
## Дочерние компоненты
|
||||||
|
|
||||||
|
Если модулю нужны внутренние подкомпоненты — [генерировать](/applied/templates-generation) их из шаблона `component` в папку `ui/` внутри родительского модуля. Дочерние компоненты не экспортируются через `index.ts` родителя.
|
||||||
|
|
||||||
|
Правила написания компонентов — [Компоненты](/applied/components).
|
||||||
|
|||||||
@@ -1,7 +1,27 @@
|
|||||||
---
|
---
|
||||||
title: Создание страниц
|
title: Добавление страницы
|
||||||
---
|
---
|
||||||
|
|
||||||
# Создание страниц
|
# Добавление страницы
|
||||||
|
|
||||||
Паттерн создания страниц: роутинг (page.tsx) и экран (screen).
|
Как добавить новую страницу в проект по стандартам этого руководства.
|
||||||
|
|
||||||
|
## Что нужно знать
|
||||||
|
|
||||||
|
Страница в проекте — это два файла: экран в `src/screens/` (вся логика, стили, зависимости) и `page.tsx` в `src/app/` (точка входа для роутинга Next.js). Экран генерируется из шаблона, `page.tsx` создаётся вручную.
|
||||||
|
|
||||||
|
## Порядок действий
|
||||||
|
|
||||||
|
1. [Сгенерировать](/applied/templates-generation) экран из шаблона `screen` в папку `src/screens/`.
|
||||||
|
|
||||||
|
2. Заполнить экран логикой и стилями.
|
||||||
|
|
||||||
|
3. Создать `page.tsx` в нужном маршруте `src/app/`. Файл страницы должен быть тонким — только `metadata` и рендер экрана. Никакой логики, стилей и хуков в `page.tsx` не размещается — всё это живёт в экране.
|
||||||
|
|
||||||
|
## Правила
|
||||||
|
|
||||||
|
- Ручное создание файловой структуры экрана запрещено — только [генерация](/applied/templates-generation) из шаблона.
|
||||||
|
- Логика, стили и зависимости размещаются в экране, не в `page.tsx`.
|
||||||
|
- Каждая страница содержит `metadata` с `title` и `description`.
|
||||||
|
|
||||||
|
Примеры `page.tsx` и `metadata` — [Page-level компоненты](/applied/page-level).
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
---
|
---
|
||||||
title: Работа с данными
|
title: Получение данных
|
||||||
---
|
---
|
||||||
|
|
||||||
# Работа с данными
|
# Получение данных
|
||||||
|
|
||||||
Как получать данные: SWR, кодген API-клиентов, сокеты.
|
Как получать данные с сервера — SWR, генерация API-клиентов, сокеты.
|
||||||
|
|||||||
@@ -4,63 +4,19 @@ title: Начало работы
|
|||||||
|
|
||||||
# Начало работы
|
# Начало работы
|
||||||
|
|
||||||
Что нужно установить и настроить перед началом разработки.
|
Что нужно знать перед началом разработки в проекте.
|
||||||
|
|
||||||
## Генерация кода
|
## Стек проекта
|
||||||
|
|
||||||
AI-ассистент создаёт компоненты, страницы и другие модули из шаблонов проекта через CLI. Установить глобально:
|
**Next.js** (App Router), **Mantine**, **Zustand**, **FSD**.
|
||||||
|
|
||||||
```bash
|
Подробнее — [Технологии и библиотеки](/basics/tech-stack).
|
||||||
npm i -g @gromlab/create
|
|
||||||
```
|
|
||||||
|
|
||||||
Подробнее: [@gromlab/create](https://www.npmjs.com/package/@gromlab/create)
|
## Ключевые особенности
|
||||||
|
|
||||||
## VS Code
|
- **Генерация вместо ручного создания** — компоненты, фичи, виджеты, сторы и другие модули не создаются вручную. Файловая структура генерируется из шаблонов `.templates/`. Ручное создание файловой структуры модулей запрещено.
|
||||||
|
- **Biome вместо ESLint + Prettier** — один инструмент для линтинга и форматирования. Автофикс и сортировка импортов происходят автоматически при сохранении файла.
|
||||||
|
|
||||||
#### Расширения
|
## Настройка окружения
|
||||||
|
|
||||||
Каждый проект должен содержать файл `.vscode/extensions.json` — VS Code автоматически предложит установить нужные расширения при открытии проекта.
|
Открыть проект в VS Code и установить рекомендуемые расширения — редактор предложит это автоматически. Подробнее — [Настройка VS Code](/applied/vscode).
|
||||||
|
|
||||||
```json
|
|
||||||
// .vscode/extensions.json
|
|
||||||
{
|
|
||||||
"recommendations": [
|
|
||||||
"biomejs.biome",
|
|
||||||
"MyTemplateGenerator.mytemplategenerator",
|
|
||||||
"csstools.postcss"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
| Расширение | Назначение |
|
|
||||||
|-----------|-----------|
|
|
||||||
| [MyTemplateGenerator](https://open-vsx.org/extension/MyTemplateGenerator/mytemplategenerator) | Генерация файлов и папок из шаблонов через UI |
|
|
||||||
| [Biome](https://marketplace.visualstudio.com/items?itemName=biomejs.biome) | Линтинг и форматирование кода |
|
|
||||||
| [PostCSS Language Support](https://marketplace.visualstudio.com/items?itemName=csstools.postcss) | Подсветка и автодополнение PostCSS |
|
|
||||||
|
|
||||||
#### Настройки
|
|
||||||
|
|
||||||
Каждый проект должен содержать файл `.vscode/settings.json` с базовой конфигурацией редактора.
|
|
||||||
|
|
||||||
```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` | Biome как форматтер по умолчанию |
|
|
||||||
| `editor.formatOnSave` | Автоформатирование при сохранении |
|
|
||||||
| `codeActionsOnSave` | Автофикс и сортировка импортов при сохранении |
|
|
||||||
| `files.associations` | CSS-файлы открываются с подсветкой PostCSS |
|
|
||||||
|
|||||||
@@ -4,4 +4,4 @@ title: Локализация
|
|||||||
|
|
||||||
# Локализация
|
# Локализация
|
||||||
|
|
||||||
Как добавлять переводы и работать с i18next.
|
Как добавлять переводы и подключать локализацию через i18next.
|
||||||
|
|||||||
@@ -4,4 +4,4 @@ title: Управление состоянием
|
|||||||
|
|
||||||
# Управление состоянием
|
# Управление состоянием
|
||||||
|
|
||||||
Когда и как создавать стор (Zustand), что хранить локально и глобально.
|
Как работать с состоянием — когда создавать стор, что хранить локально и глобально.
|
||||||
|
|||||||
@@ -4,4 +4,20 @@ title: Стилизация
|
|||||||
|
|
||||||
# Стилизация
|
# Стилизация
|
||||||
|
|
||||||
Приоритет инструментов стилизации и правила их применения.
|
Как стилизовать компоненты в проекте — приоритет инструментов и правила их применения.
|
||||||
|
|
||||||
|
## Приоритет стилизации
|
||||||
|
|
||||||
|
Основной UI-фреймворк проекта — **Mantine**. При стилизации компонентов придерживаться следующего приоритета:
|
||||||
|
|
||||||
|
1. **Mantine-компоненты и их пропсы** — в первую очередь использовать встроенные возможности Mantine (пропсы, `classNames`, `styles`).
|
||||||
|
2. **Глобальные CSS-токены** (`--color-*`, `--space-*`, `--radius-*`) — для значений, которые не покрываются Mantine.
|
||||||
|
3. **PostCSS Modules** — когда Mantine не покрывает задачу и нужна кастомная стилизация.
|
||||||
|
|
||||||
|
## Что запрещено
|
||||||
|
|
||||||
|
- **Инлайн-стили** — использование атрибута `style` в компонентах строго запрещено.
|
||||||
|
- **Магические значения** — произвольные цвета, отступы и скругления запрещены, использовать токены.
|
||||||
|
- **Глобальные стили** вне `app/styles/` запрещены.
|
||||||
|
|
||||||
|
Правила написания CSS, вложенность, медиа-запросы и токены — [Стили](/applied/styles).
|
||||||
|
|||||||
@@ -1,6 +1,4 @@
|
|||||||
|
<!-- /index -->
|
||||||
<a name="indexmd"></a>
|
|
||||||
|
|
||||||
# NextJS Style Guide
|
# NextJS Style Guide
|
||||||
|
|
||||||
Rules and standards for NextJS and TypeScript development: architecture, typing, styles, components, API, and infrastructure.
|
Rules and standards for NextJS and TypeScript development: architecture, typing, styles, components, API, and infrastructure.
|
||||||
@@ -43,6 +41,7 @@ Rules and standards for NextJS and TypeScript development: architecture, typing,
|
|||||||
|---------|---------------------|
|
|---------|---------------------|
|
||||||
| Project Structure | How are folders and files organized by FSD? |
|
| Project Structure | How are folders and files organized by FSD? |
|
||||||
| Components | How is a component structured: files, props, clsx, FC? |
|
| Components | How is a component structured: files, props, clsx, FC? |
|
||||||
|
| Page-level Components | How to define layout, page, loading, error, not-found? |
|
||||||
| Templates & Code Generation | How do templates work: syntax, variables, modifiers? |
|
| Templates & Code Generation | How do templates work: syntax, variables, modifiers? |
|
||||||
| Styles | How to write CSS: PostCSS Modules, nesting, media, tokens? |
|
| Styles | How to write CSS: PostCSS Modules, nesting, media, tokens? |
|
||||||
| Images | _(not filled)_ |
|
| Images | _(not filled)_ |
|
||||||
@@ -58,168 +57,121 @@ Rules and standards for NextJS and TypeScript development: architecture, typing,
|
|||||||
|
|
||||||
Full documentation in a single MD file: https://gromlab.ru/docs/frontend-style-guide/raw/branch/main/generated/en/RULES.md
|
Full documentation in a single MD file: https://gromlab.ru/docs/frontend-style-guide/raw/branch/main/generated/en/RULES.md
|
||||||
|
|
||||||
|
<!-- /workflow/getting-started -->
|
||||||
<a name="workflowgetting-startedmd"></a>
|
## Getting Started
|
||||||
|
|
||||||
# Getting Started
|
|
||||||
|
|
||||||
Setting up the environment and installing tools before starting development.
|
Setting up the environment and installing tools before starting development.
|
||||||
|
|
||||||
|
<!-- /workflow/creating-app -->
|
||||||
<a name="workflowcreating-appmd"></a>
|
## Creating an App
|
||||||
|
|
||||||
# Creating an App
|
|
||||||
|
|
||||||
How to create a new application: choosing a project template and initialization.
|
How to create a new application: choosing a project template and initialization.
|
||||||
|
|
||||||
|
<!-- /workflow/creating-pages -->
|
||||||
<a name="workflowcreating-pagesmd"></a>
|
## Creating Pages
|
||||||
|
|
||||||
# Creating Pages
|
|
||||||
|
|
||||||
Page creation pattern: routing (page.tsx) and screen.
|
Page creation pattern: routing (page.tsx) and screen.
|
||||||
|
|
||||||
|
<!-- /workflow/creating-components -->
|
||||||
<a name="workflowcreating-componentsmd"></a>
|
## Creating Components
|
||||||
|
|
||||||
# Creating Components
|
|
||||||
|
|
||||||
Generating components using templates, working with child components.
|
Generating components using templates, working with child components.
|
||||||
|
|
||||||
|
<!-- /workflow/styling -->
|
||||||
<a name="workflowstylingmd"></a>
|
## Styling
|
||||||
|
|
||||||
# Styling
|
|
||||||
|
|
||||||
Styling tools priority and rules for their application.
|
Styling tools priority and rules for their application.
|
||||||
|
|
||||||
|
<!-- /workflow/data-fetching -->
|
||||||
<a name="workflowdata-fetchingmd"></a>
|
## Data Fetching
|
||||||
|
|
||||||
# Data Fetching
|
|
||||||
|
|
||||||
How to fetch data: SWR, API client codegen, sockets.
|
How to fetch data: SWR, API client codegen, sockets.
|
||||||
|
|
||||||
|
<!-- /workflow/state-management -->
|
||||||
<a name="workflowstate-managementmd"></a>
|
## State Management
|
||||||
|
|
||||||
# State Management
|
|
||||||
|
|
||||||
When and how to create a store (Zustand), what to store locally vs globally.
|
When and how to create a store (Zustand), what to store locally vs globally.
|
||||||
|
|
||||||
|
<!-- /workflow/localization -->
|
||||||
<a name="workflowlocalizationmd"></a>
|
## Localization
|
||||||
|
|
||||||
# Localization
|
|
||||||
|
|
||||||
How to add translations and work with i18next.
|
How to add translations and work with i18next.
|
||||||
|
|
||||||
|
<!-- /basics/tech-stack -->
|
||||||
<a name="basicstech-stackmd"></a>
|
## Tech Stack
|
||||||
|
|
||||||
# Tech Stack
|
|
||||||
|
|
||||||
Base technology stack and libraries used in projects.
|
Base technology stack and libraries used in projects.
|
||||||
|
|
||||||
|
<!-- /basics/architecture -->
|
||||||
<a name="basicsarchitecturemd"></a>
|
## Architecture
|
||||||
|
|
||||||
# Architecture
|
|
||||||
|
|
||||||
Architecture based on FSD (Feature-Sliced Design) and strict module boundaries.
|
Architecture based on FSD (Feature-Sliced Design) and strict module boundaries.
|
||||||
|
|
||||||
|
<!-- /basics/code-style -->
|
||||||
<a name="basicscode-stylemd"></a>
|
## Code Style
|
||||||
|
|
||||||
# Code Style
|
|
||||||
|
|
||||||
Unified code formatting rules: indentation, line breaks, quotes, import order, and readability.
|
Unified code formatting rules: indentation, line breaks, quotes, import order, and readability.
|
||||||
|
|
||||||
|
<!-- /basics/naming -->
|
||||||
<a name="basicsnamingmd"></a>
|
## Naming
|
||||||
|
|
||||||
# Naming
|
|
||||||
|
|
||||||
Naming should be predictable, concise, and reflect the meaning of the entity.
|
Naming should be predictable, concise, and reflect the meaning of the entity.
|
||||||
|
|
||||||
|
<!-- /basics/documentation -->
|
||||||
<a name="basicsdocumentationmd"></a>
|
## Documentation
|
||||||
|
|
||||||
# Documentation
|
|
||||||
|
|
||||||
Documentation should help understand the purpose of an entity, not duplicate its types or obvious details.
|
Documentation should help understand the purpose of an entity, not duplicate its types or obvious details.
|
||||||
|
|
||||||
|
<!-- /basics/typing -->
|
||||||
<a name="basicstypingmd"></a>
|
## Typing
|
||||||
|
|
||||||
# Typing
|
|
||||||
|
|
||||||
Typing is required for all public interfaces, functions, and components.
|
Typing is required for all public interfaces, functions, and components.
|
||||||
|
|
||||||
|
<!-- /applied/project-structure -->
|
||||||
<a name="appliedproject-structuremd"></a>
|
## Project Structure
|
||||||
|
|
||||||
# Project Structure
|
|
||||||
|
|
||||||
Base project structure and principles of module organization at folder and file level.
|
Base project structure and principles of module organization at folder and file level.
|
||||||
|
|
||||||
|
<!-- /applied/components -->
|
||||||
<a name="appliedcomponentsmd"></a>
|
## Components
|
||||||
|
|
||||||
# Components
|
|
||||||
|
|
||||||
Rules for creating UI components across all FSD layers.
|
Rules for creating UI components across all FSD layers.
|
||||||
|
|
||||||
|
<!-- /applied/page-level -->
|
||||||
|
## Page-level Components
|
||||||
|
|
||||||
<a name="appliedtemplates-generationmd"></a>
|
Next.js App Router special files used by the framework by convention: `layout.tsx`, `page.tsx`, `loading.tsx`, `error.tsx`, `not-found.tsx`, `template.tsx`.
|
||||||
|
|
||||||
# Templates & Code Generation
|
<!-- /applied/templates-generation -->
|
||||||
|
## Templates & Code Generation
|
||||||
|
|
||||||
Template tools, syntax, and examples for code generation.
|
Template tools, syntax, and examples for code generation.
|
||||||
|
|
||||||
|
<!-- /applied/styles -->
|
||||||
<a name="appliedstylesmd"></a>
|
## Styles
|
||||||
|
|
||||||
# Styles
|
|
||||||
|
|
||||||
CSS writing rules: PostCSS Modules, nesting, media queries, variables, formatting.
|
CSS writing rules: PostCSS Modules, nesting, media queries, variables, formatting.
|
||||||
|
|
||||||
|
<!-- /applied/images-sprites -->
|
||||||
|
## Images
|
||||||
|
|
||||||
<a name="appliedimages-spritesmd"></a>
|
<!-- /applied/svg-sprites -->
|
||||||
|
## SVG Sprites
|
||||||
|
|
||||||
# Images
|
<!-- /applied/video -->
|
||||||
|
## Video
|
||||||
|
|
||||||
|
<!-- /applied/api -->
|
||||||
|
## API
|
||||||
|
|
||||||
<a name="appliedsvg-spritesmd"></a>
|
<!-- /applied/stores -->
|
||||||
|
## Stores
|
||||||
|
|
||||||
# SVG Sprites
|
<!-- /applied/hooks -->
|
||||||
|
## Hooks
|
||||||
|
|
||||||
|
<!-- /applied/fonts -->
|
||||||
|
## Fonts
|
||||||
|
|
||||||
<a name="appliedvideomd"></a>
|
<!-- /applied/localization -->
|
||||||
|
## Localization
|
||||||
# Video
|
|
||||||
|
|
||||||
|
|
||||||
<a name="appliedapimd"></a>
|
|
||||||
|
|
||||||
# API
|
|
||||||
|
|
||||||
|
|
||||||
<a name="appliedstoresmd"></a>
|
|
||||||
|
|
||||||
# Stores
|
|
||||||
|
|
||||||
|
|
||||||
<a name="appliedhooksmd"></a>
|
|
||||||
|
|
||||||
# Hooks
|
|
||||||
|
|
||||||
|
|
||||||
<a name="appliedfontsmd"></a>
|
|
||||||
|
|
||||||
# Fonts
|
|
||||||
|
|
||||||
|
|
||||||
<a name="appliedlocalizationmd"></a>
|
|
||||||
|
|
||||||
# Localization
|
|
||||||
File diff suppressed because it is too large
Load Diff
3321
package-lock.json
generated
3321
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -9,9 +9,7 @@
|
|||||||
"build": "vitepress build .",
|
"build": "vitepress build .",
|
||||||
"serve": "vitepress serve ."
|
"serve": "vitepress serve ."
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {},
|
||||||
"concat-md": "^0.5.1"
|
|
||||||
},
|
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"vitepress": "^1.6.3"
|
"vitepress": "^1.6.3"
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user