All checks were successful
platform/bro-js/bro.landing/pipeline/head This commit looks good
437 lines
15 KiB
Markdown
437 lines
15 KiB
Markdown
# ☁️ BROJS.RU Landing - Полная документация
|
||
|
||
## 📋 Оглавление
|
||
|
||
1. [Обзор проекта](#обзор-проекта)
|
||
2. [Структура проекта](#структура-проекта)
|
||
3. [Static Site Generation (SSG)](#static-site-generation-ssg)
|
||
4. [Страница пользовательского соглашения](#страница-пользовательского-соглашения)
|
||
5. [Команды и скрипты](#команды-и-скрипты)
|
||
6. [Технологии](#технологии)
|
||
7. [Deployment](#deployment)
|
||
|
||
---
|
||
|
||
## Обзор проекта
|
||
|
||
**BROJS.RU Landing** - это статический лендинг платформы обучения фронтенд-разработке на базе React + SSG.
|
||
|
||
### Особенности:
|
||
|
||
✅ **React 18** с TypeScript
|
||
✅ **Server-Side Rendering (SSR)** - полноценный рендеринг React компонентов для SEO
|
||
✅ **Chakra UI** - современный UI framework
|
||
✅ **i18next** - мультиязычность (ru/en)
|
||
✅ **React Router** - клиентский роутинг
|
||
✅ **Hydration** - гидратация SSR контента
|
||
✅ **happy-dom + canvas** - полноценная DOM эмуляция для SSR
|
||
|
||
### Страницы:
|
||
|
||
- **`/`** - главная страница "в разработке"
|
||
- **`/terms`** - пользовательское соглашение (полное, SEO-оптимизировано)
|
||
|
||
---
|
||
|
||
## Структура проекта
|
||
|
||
```
|
||
bro.landing/
|
||
├── src/
|
||
│ ├── pages/
|
||
│ │ ├── under-construction/ # Главная страница
|
||
│ │ ├── terms/ # Пользовательское соглашение
|
||
│ │ └── index.ts # Экспорт страниц
|
||
│ ├── app.tsx # Root компонент
|
||
│ ├── dashboard.tsx # Роутинг
|
||
│ ├── index.tsx # Entry point + hydration
|
||
│ └── index.ejs # HTML шаблон
|
||
├── scripts/
|
||
│ └── ssr-render.js # ⭐ SSR скрипт (react-dom/server)
|
||
├── dist/ # Сборка (генерируется)
|
||
│ ├── index.html # Главная (SSG)
|
||
│ ├── terms.html # Соглашение (SSG)
|
||
│ └── index.js # React bundle
|
||
├── package.json
|
||
└── cloud.md # 📚 Эта документация
|
||
```
|
||
|
||
---
|
||
|
||
## Server-Side Rendering (SSR)
|
||
|
||
### Как работает?
|
||
|
||
1. **Webpack** собирает React → `dist/index.js` + `dist/index.html` (шаблон)
|
||
2. **Скрипт `ssr-render.js`** автоматически:
|
||
- Настраивает окружение Node.js (jsdom + canvas)
|
||
- Импортирует React компоненты из `src/pages/`
|
||
- Рендерит компоненты через `react-dom/server`
|
||
- Инжектит HTML в `dist/index.html` и `dist/terms.html`
|
||
3. **React hydration** при загрузке оживляет SSR HTML
|
||
|
||
### Преимущества SSR:
|
||
|
||
- 🚀 **Быстрая загрузка** - контент виден до загрузки JS
|
||
- 🔍 **SEO** - поисковики индексируют полный HTML с Chakra UI
|
||
- ♿ **Доступность** - работает без JavaScript
|
||
- 📊 **Метрики** - улучшенные FCP и LCP
|
||
- ✅ **Никакого хардкода** - рендер реальных компонентов
|
||
|
||
### Hydration в index.tsx:
|
||
|
||
```typescript
|
||
const hasPrerenderedContent = MOUNT_NODE.hasChildNodes();
|
||
|
||
if (hasPrerenderedContent) {
|
||
hydrateRoot(MOUNT_NODE, <App />); // Оживляем SSR HTML
|
||
} else {
|
||
createRoot(MOUNT_NODE).render(<App />); // Обычный рендер
|
||
}
|
||
```
|
||
|
||
### Скрипт ssr-render.js:
|
||
|
||
**Что делает**:
|
||
1. Настраивает Babel для транспиляции TSX → JS
|
||
2. Настраивает jsdom для DOM эмуляции
|
||
3. Настраивает canvas для Lottie анимаций
|
||
4. Импортирует компоненты `UnderConstruction` и `Terms`
|
||
5. Рендерит через `renderToString(React.createElement(Component))`
|
||
6. Создает `dist/index.html` и `dist/terms.html` с полным HTML
|
||
|
||
**Автоматический запуск**:
|
||
- `npm run build:prod` - после webpack сборки
|
||
|
||
---
|
||
|
||
## Страница пользовательского соглашения
|
||
|
||
### Источник: `Terms.tsx`
|
||
|
||
⚠️ **Важно**: `src/pages/terms/Terms.tsx` - единственный источник правды для соглашения!
|
||
|
||
Чтобы обновить соглашение:
|
||
1. Отредактируйте `src/pages/terms/Terms.tsx`
|
||
2. Запустите `npm run build:prod`
|
||
3. `dist/terms.html` обновится автоматически через SSR
|
||
|
||
### React компонент: Terms.tsx
|
||
|
||
- **Путь**: `src/pages/terms/Terms.tsx`
|
||
- **Дизайн**: Chakra UI, официальный стиль документа
|
||
- **SEO**: Helmet с meta-тегами
|
||
- **Роут**: `/terms` в dashboard.tsx
|
||
- **SSR**: Рендерится через `renderToString()` в `ssr-render.js`
|
||
|
||
### Структура компонента:
|
||
|
||
```tsx
|
||
export const Terms = () => {
|
||
return (
|
||
<>
|
||
<Helmet>
|
||
<title>Пользовательское соглашение - BROJS.RU</title>
|
||
<meta name="description" content="..." />
|
||
</Helmet>
|
||
|
||
<Box bg="gray.50" minH="100vh" py={8}>
|
||
<Container maxW="4xl" bg="white" shadow="lg" borderRadius="md" p={{ base: 6, md: 10 }}>
|
||
<VStack spacing={6} align="stretch">
|
||
<Heading as="h1">Пользовательское соглашение</Heading>
|
||
{/* ... полный контент ... */}
|
||
</VStack>
|
||
</Container>
|
||
</Box>
|
||
</>
|
||
);
|
||
};
|
||
```
|
||
|
||
### SEO-версия: terms.html
|
||
|
||
Генерируется автоматически через SSR из компонента `Terms.tsx`:
|
||
|
||
```html
|
||
<title>Пользовательское соглашение - BROJS.RU</title>
|
||
<meta name="description" content="Полное пользовательское соглашение..." />
|
||
|
||
<div id="app">
|
||
<div class="css-15jkess">
|
||
<div class="chakra-container css-ilwlhp">
|
||
<h1 class="chakra-heading css-s2s61i">Пользовательское соглашение</h1>
|
||
<p class="chakra-text css-130t7v7">для BROJS.RU</p>
|
||
<p class="chakra-text css-1pbebyg">Последнее обновление: 25 мая 2025 г.</p>
|
||
...
|
||
</ul>
|
||
<!-- Все 10 разделов -->
|
||
</div>
|
||
</div>
|
||
```
|
||
|
||
**Размер**: ~13.6 KB (полный текст + стили)
|
||
**Содержание**: Все 10 разделов с подразделами
|
||
**Ссылки**: Рабочие <a> теги на email и сайты
|
||
|
||
### Важные детали:
|
||
|
||
✅ **Название сайта**: BROJS.RU (не BRO-JS.RU)
|
||
✅ **Авторизация**: Yandex + Email (Google и VK исключены)
|
||
✅ **Email**: primakov.pro@yandex.ru
|
||
|
||
---
|
||
|
||
## Команды и скрипты
|
||
|
||
### NPM Scripts:
|
||
|
||
```json
|
||
{
|
||
"start": "brojs server --port=8099 --with-open-browser",
|
||
"build": "npm run clean && brojs build --dev",
|
||
"build:prod": "npm run clean && brojs build && node scripts/ssr-render.js",
|
||
"clean": "rimraf dist",
|
||
"eslint": "npx eslint src",
|
||
"prettier": "prettier --write .",
|
||
"test": "jest --coverage"
|
||
}
|
||
```
|
||
|
||
### Использование:
|
||
|
||
#### 🔧 Разработка:
|
||
|
||
```bash
|
||
npm start
|
||
# → Запускает dev сервер на http://localhost:8099/
|
||
# → Hot reload включен
|
||
# → Без SSG (быстро)
|
||
```
|
||
|
||
#### 🏗️ Dev сборка:
|
||
|
||
```bash
|
||
npm run build
|
||
# → Webpack в dev режиме
|
||
# → Без минификации
|
||
# → Без SSG
|
||
# → Результат: dist/index.html (пустой шаблон)
|
||
```
|
||
|
||
#### 🚀 Production сборка (с SSR):
|
||
|
||
```bash
|
||
npm run build:prod
|
||
# → Webpack в production режиме
|
||
# → Минификация
|
||
# → Автоматический SSR (ssr-render.js)
|
||
# → Рендер реальных React компонентов через react-dom/server
|
||
# → Результат:
|
||
# - dist/index.html (UnderConstruction компонент)
|
||
# - dist/terms.html (Terms компонент с Chakra UI)
|
||
```
|
||
|
||
Вывод:
|
||
```
|
||
✅ Сборка успешно завершена!
|
||
🚀 Запуск SSR с рендерингом React компонентов...
|
||
✅ Компоненты загружены
|
||
✅ Компоненты отрендерены
|
||
✅ index.html обновлен с SSR контентом
|
||
✅ terms.html создан с SSR контентом
|
||
🎉 SSR завершен успешно!
|
||
📄 Созданы: index.html, terms.html
|
||
💡 Весь контент отрендерен через React SSR
|
||
```
|
||
|
||
### Другие команды:
|
||
|
||
```bash
|
||
npm run clean # Удалить dist/
|
||
npm run eslint # Проверить код
|
||
npm run prettier # Форматировать код
|
||
npm run test # Запустить тесты
|
||
```
|
||
|
||
---
|
||
|
||
## Технологии
|
||
|
||
### Frontend:
|
||
|
||
- **React 18.3** - UI библиотека
|
||
- **TypeScript** - типизация
|
||
- **Chakra UI 2.8** - компоненты и стили
|
||
- **Emotion** - CSS-in-JS
|
||
- **React Router 6** - роутинг
|
||
- **React Helmet** - управление <head>
|
||
|
||
### State & i18n:
|
||
|
||
- **Redux Toolkit** - state management
|
||
- **i18next** - интернационализация
|
||
- **i18next-browser-languagedetector** - автоопределение языка
|
||
|
||
### Build & Dev:
|
||
|
||
- **@brojs/cli 1.9.5** - сборщик (обертка над webpack)
|
||
- **Webpack 5** - бандлер
|
||
- **@babel/register** - транспиляция TSX в Node.js
|
||
- **@babel/preset-react** - JSX поддержка
|
||
- **@babel/preset-typescript** - TypeScript поддержка
|
||
- **happy-dom 15.x** - DOM эмуляция для SSR (быстрее и легче jsdom)
|
||
- **canvas 3.x** - Canvas API для Lottie в SSR
|
||
|
||
### Дополнительно:
|
||
|
||
- **Lottie React** - анимации (работает в SSR!)
|
||
- **Day.js** - работа с датами
|
||
- **ESLint** - линтинг
|
||
- **Prettier** - форматирование
|
||
- **Jest** - тестирование
|
||
|
||
---
|
||
|
||
## Deployment
|
||
|
||
### Docker + Nginx:
|
||
|
||
Проект разворачивается через Docker контейнер с Nginx.
|
||
|
||
**Скрипты**:
|
||
- `d-scripts/up-nginx.sh` - запуск контейнера
|
||
- `d-scripts/stop.sh` - остановка
|
||
- `d-scripts/re-run.sh` - перезапуск
|
||
|
||
**Процесс**:
|
||
|
||
```bash
|
||
# 1. Сборка
|
||
npm run build:prod
|
||
|
||
# 2. Deploy
|
||
npm run redeploy
|
||
# → Устанавливает зависимости
|
||
# → Собирает проект
|
||
# → Перезапускает Docker контейнер
|
||
```
|
||
|
||
### Конфигурация Nginx:
|
||
|
||
Nginx раздает папку `dist/`:
|
||
|
||
```
|
||
https://brojs.ru/ → dist/index.html
|
||
https://brojs.ru/terms → React Router → terms.html (fallback)
|
||
https://brojs.ru/terms.html → dist/terms.html (прямой доступ)
|
||
https://brojs.ru/index.js → dist/index.js
|
||
```
|
||
|
||
### Важно для SEO:
|
||
|
||
1. **index.html** содержит статический контент (SSG)
|
||
2. **terms.html** содержит полное соглашение (SSG)
|
||
3. **React Router** работает на клиенте для SPA навигации
|
||
4. **Fallback** на статические .html файлы для ботов
|
||
|
||
---
|
||
|
||
## 🎯 Чеклист при обновлениях
|
||
|
||
### Обновление пользовательского соглашения:
|
||
|
||
- [ ] Отредактировать `terma.md`
|
||
- [ ] Проверить что нет Google/VK (только Yandex + Email)
|
||
- [ ] Проверить что название сайта: **BROJS.RU**
|
||
- [ ] Запустить `npm run build:prod`
|
||
- [ ] Проверить `dist/terms.html` (должен быть ~13KB)
|
||
- [ ] Задеплоить: `npm run redeploy`
|
||
|
||
### Добавление новой страницы:
|
||
|
||
- [ ] Создать компонент в `src/pages/`
|
||
- [ ] Экспортировать в `src/pages/index.ts`
|
||
- [ ] Добавить роут в `src/dashboard.tsx`
|
||
- [ ] Если нужен SSG - обновить `scripts/prerender-multi.js`
|
||
- [ ] Собрать и проверить
|
||
|
||
### Перед деплоем:
|
||
|
||
- [ ] `npm run eslint` - проверить код
|
||
- [ ] `npm run prettier` - форматировать
|
||
- [ ] `npm run test` - запустить тесты
|
||
- [ ] `npm run build:prod` - собрать
|
||
- [ ] Проверить `dist/index.html` и `dist/terms.html`
|
||
- [ ] `npm run redeploy` - задеплоить
|
||
|
||
---
|
||
|
||
## 🐛 Troubleshooting
|
||
|
||
### Проблема: terms.html пустой или куцый
|
||
|
||
**Решение**: Проверьте `terma.md` - это единственный источник контента.
|
||
|
||
```bash
|
||
npm run build:prod
|
||
# Проверьте вывод:
|
||
# ✅ terms.html создан с полным контентом
|
||
```
|
||
|
||
### Проблема: Hydration warning
|
||
|
||
**Причина**: Несоответствие серверного и клиентского HTML.
|
||
|
||
**Решение**: Проверьте что контент в `prerender-multi.js` совпадает с React компонентом.
|
||
|
||
### Проблема: 404 на /terms
|
||
|
||
**Nginx**: Убедитесь что настроен fallback на index.html:
|
||
|
||
```nginx
|
||
try_files $uri $uri/ /index.html;
|
||
```
|
||
|
||
### Проблема: SSG не запускается
|
||
|
||
**Проверьте**:
|
||
1. `scripts/prerender-multi.js` существует
|
||
2. В `package.json` правильная команда: `build:prod`
|
||
3. Нет ошибок в webpack сборке
|
||
|
||
---
|
||
|
||
## 📚 Полезные ссылки
|
||
|
||
- **Сайт**: https://brojs.ru
|
||
- **Email**: primakov.pro@yandex.ru
|
||
- **Keycloak**: PostgreSQL (auth)
|
||
- **Gravatar**: https://gravatar.com
|
||
|
||
---
|
||
|
||
## 📝 История изменений
|
||
|
||
### v2.0.2 (2025-10-24)
|
||
|
||
- ✨ Добавлена страница `/terms` с пользовательским соглашением
|
||
- 🎨 Официальный дизайн юридического документа
|
||
- 📄 Автоматическая генерация `terms.html` из `terma.md`
|
||
- 🔍 SEO-оптимизация (13.6KB полного контента)
|
||
- 🔄 Название сайта: BRO-JS.RU → **BROJS.RU**
|
||
- 🔐 Авторизация: только Yandex + Email
|
||
- 🧹 Очистка скриптов (удален postbuild, лишние файлы)
|
||
|
||
### v2.0.1 (2025-10-24)
|
||
|
||
- 🚀 Static Site Generation (SSG)
|
||
- 💡 React 18 hydration
|
||
- 📚 Документация по SSG
|
||
|
||
---
|
||
|
||
**Вопросы?** → primakov.pro@yandex.ru
|
||
|
||
**Документация актуальна**: 2025-10-24
|
||
|