16 KiB
☁️ BROJS.RU Landing - Полная документация
📋 Оглавление
- Обзор проекта
- Структура проекта
- Static Site Generation (SSG)
- Страница пользовательского соглашения
- Команды и скрипты
- Технологии
- 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/
│ ├── styles/
│ │ ├── main.module.scss # CSS Modules для React компонентов
│ │ ├── main.module.scss.d.ts # TypeScript типы для CSS Modules
│ │ └── terms.scss # Обычный SCSS для статической страницы
│ ├── pages/
│ │ └── under-construction/ # Главная страница (React)
│ ├── index.tsx # Entry point для главной страницы
│ ├── terms.js # Entry point для стилей Terms
│ ├── terms.html # Статический HTML Terms страницы
│ ├── index.ejs # HTML шаблон для React страницы
│ └── app.tsx # React приложение
├── dist/ # Собранные файлы
│ ├── index.html # Главная (с React)
│ ├── index.js + index.css # Бандлы главной
│ ├── terms.html # Terms (чистый HTML + CSS)
│ └── terms.css # Стили Terms
├── ijl.config.js # Webpack конфигурация
└── package.json
Структура проекта
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)
Как работает?
- Webpack собирает React →
dist/index.js+dist/index.html(шаблон) - Скрипт
ssr-render.jsавтоматически:- Настраивает окружение Node.js (jsdom + canvas)
- Импортирует React компоненты из
src/pages/ - Рендерит компоненты через
react-dom/server - Инжектит HTML в
dist/index.htmlиdist/terms.html
- React hydration при загрузке оживляет SSR HTML
Преимущества SSR:
- 🚀 Быстрая загрузка - контент виден до загрузки JS
- 🔍 SEO - поисковики индексируют полный HTML с Chakra UI
- ♿ Доступность - работает без JavaScript
- 📊 Метрики - улучшенные FCP и LCP
- ✅ Никакого хардкода - рендер реальных компонентов
Hydration в index.tsx:
const hasPrerenderedContent = MOUNT_NODE.hasChildNodes();
if (hasPrerenderedContent) {
hydrateRoot(MOUNT_NODE, <App />); // Оживляем SSR HTML
} else {
createRoot(MOUNT_NODE).render(<App />); // Обычный рендер
}
Скрипт ssr-render.js:
Что делает:
- Настраивает Babel для транспиляции TSX → JS
- Настраивает jsdom для DOM эмуляции
- Настраивает canvas для Lottie анимаций
- Импортирует компоненты
UnderConstructionиTerms - Рендерит через
renderToString(React.createElement(Component)) - Создает
dist/index.htmlиdist/terms.htmlс полным HTML
Автоматический запуск:
npm run build:prod- после webpack сборки
Страница пользовательского соглашения
Источник: Terms.tsx
⚠️ Важно: src/pages/terms/Terms.tsx - единственный источник правды для соглашения!
Чтобы обновить соглашение:
- Отредактируйте
src/pages/terms/Terms.tsx - Запустите
npm run build:prod 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
Структура компонента:
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:
<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 разделов с подразделами
Ссылки: Рабочие теги на email и сайты
Важные детали:
✅ Название сайта: BROJS.RU (не BRO-JS.RU)
✅ Авторизация: Yandex + Email (Google и VK исключены)
✅ Email: primakov.pro@yandex.ru
Команды и скрипты
NPM Scripts:
{
"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"
}
Использование:
🔧 Разработка:
npm start
# → Запускает dev сервер на http://localhost:8099/
# → Hot reload включен
# → Без SSG (быстро)
🏗️ Dev сборка:
npm run build
# → Webpack в dev режиме
# → Без минификации
# → Без SSG
# → Результат: dist/index.html (пустой шаблон)
🚀 Production сборка (с SSR):
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
Другие команды:
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- перезапуск
Процесс:
# 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:
- index.html содержит статический контент (SSG)
- terms.html содержит полное соглашение (SSG)
- React Router работает на клиенте для SPA навигации
- 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 - это единственный источник контента.
npm run build:prod
# Проверьте вывод:
# ✅ terms.html создан с полным контентом
Проблема: Hydration warning
Причина: Несоответствие серверного и клиентского HTML.
Решение: Проверьте что контент в prerender-multi.js совпадает с React компонентом.
Проблема: 404 на /terms
Nginx: Убедитесь что настроен fallback на index.html:
try_files $uri $uri/ /index.html;
Проблема: SSG не запускается
Проверьте:
scripts/prerender-multi.jsсуществует- В
package.jsonправильная команда:build:prod - Нет ошибок в 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