Refactor SSR implementation and update documentation. Replaced Static Site Generation (SSG) with Server-Side Rendering (SSR) using react-dom/server. Updated scripts for SSR rendering and removed deprecated prerender-multi.js. Enhanced terms.html generation from React components. Updated dependencies for Babel and added support for canvas in SSR.
platform/bro-js/bro.landing/pipeline/head This commit looks good

This commit is contained in:
Primakov Alexandr Alexandrovich
2025-10-24 11:34:04 +03:00
parent 9110e79d6b
commit 08ffd5a740
6 changed files with 765 additions and 347 deletions
+78 -66
View File
@@ -19,11 +19,12 @@
### Особенности:
**React 18** с TypeScript
**Static Site Generation** - HTML вкомпилирован для SEO
**Server-Side Rendering (SSR)** - полноценный рендеринг React компонентов для SEO
**Chakra UI** - современный UI framework
**i18next** - мультиязычность (ru/en)
**React Router** - клиентский роутинг
**Hydration** - гидратация статического контента
**Hydration** - гидратация SSR контента
**jsdom + canvas** - полноценная DOM эмуляция для SSR
### Страницы:
@@ -46,8 +47,7 @@ bro.landing/
│ ├── index.tsx # Entry point + hydration
│ └── index.ejs # HTML шаблон
├── scripts/
── prerender-multi.js # ⭐ Основной SSG скрипт
│ └── ssr-prerender.js # Альтернативный SSR
── ssr-render.js # ⭐ SSR скрипт (react-dom/server)
├── dist/ # Сборка (генерируется)
│ ├── index.html # Главная (SSG)
│ ├── terms.html # Соглашение (SSG)
@@ -58,23 +58,25 @@ bro.landing/
---
## Static Site Generation (SSG)
## Server-Side Rendering (SSR)
### Как работает?
1. **Webpack** собирает React → `dist/index.js`
2. **Скрипт `prerender-multi.js`** автоматически:
- Читает `dist/index.html` (пустой шаблон)
- Вставляет статический контент в `<div id="app"></div>`
- Генерирует `dist/terms.html` из `terma.md`
3. **React hydration** при загрузке оживляет статический HTML
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
### Преимущества SSG:
### Преимущества SSR:
- 🚀 **Быстрая загрузка** - контент виден до загрузки JS
- 🔍 **SEO** - поисковики индексируют полный HTML
- 🔍 **SEO** - поисковики индексируют полный HTML с Chakra UI
-**Доступность** - работает без JavaScript
- 📊 **Метрики** - улучшенные FCP и LCP
-**Никакого хардкода** - рендер реальных компонентов
### Hydration в index.tsx:
@@ -82,49 +84,37 @@ bro.landing/
const hasPrerenderedContent = MOUNT_NODE.hasChildNodes();
if (hasPrerenderedContent) {
hydrateRoot(MOUNT_NODE, <App />); // Оживляем статику
hydrateRoot(MOUNT_NODE, <App />); // Оживляем SSR HTML
} else {
createRoot(MOUNT_NODE).render(<App />); // Обычный рендер
}
```
### Скрипт prerender-multi.js:
### Скрипт ssr-render.js:
**Что делает**:
1. Читает `terma.md` (исходник соглашения)
2. Парсит markdown → HTML со стилями
3. Создает `dist/index.html` с контентом главной
4. Создает `dist/terms.html` с полным соглашением (~13KB)
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 сборки
- `npm run build:prod:ssr` - альтернативный SSR
---
## Страница пользовательского соглашения
### Источник: `terma.md`
### Источник: `Terms.tsx`
⚠️ **Важно**: `terma.md` - единственный источник правды для соглашения!
⚠️ **Важно**: `src/pages/terms/Terms.tsx` - единственный источник правды для соглашения!
Чтобы обновить соглашение:
1. Отредактируйте `terma.md`
1. Отредактируйте `src/pages/terms/Terms.tsx`
2. Запустите `npm run build:prod`
3. `dist/terms.html` обновится автоматически
### Структура terma.md:
```markdown
Пользовательское соглашение для BROJS.RU
Последнее обновление: 25 мая 2025 г.
1. Термины
...
10. Контакты
Для обращений: primakov.pro@yandex.ru
```
3. `dist/terms.html` обновится автоматически через SSR
### React компонент: Terms.tsx
@@ -132,21 +122,46 @@ if (hasPrerenderedContent) {
- **Дизайн**: 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
Генерируется автоматически из `terma.md`:
Генерируется автоматически через SSR из компонента `Terms.tsx`:
```html
<title>Пользовательское соглашение - BROJS.RU</title>
<meta name="description" content="Полное пользовательское соглашение..." />
<div id="app">
<div style="...красивые стили...">
<h1>Пользовательское соглашение для BROJS.RU</h1>
<h2>1. Термины</h2>
<ul>
<li>Платформа — сайт https://brojs.ru ...</li>
<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 разделов -->
@@ -174,8 +189,7 @@ if (hasPrerenderedContent) {
{
"start": "brojs server --port=8099 --with-open-browser",
"build": "npm run clean && brojs build --dev",
"build:prod": "npm run clean && brojs build && node scripts/prerender-multi.js",
"build:prod:ssr": "npm run clean && brojs build && node scripts/ssr-prerender.js",
"build:prod": "npm run clean && brojs build && node scripts/ssr-render.js",
"clean": "rimraf dist",
"eslint": "npx eslint src",
"prettier": "prettier --write .",
@@ -204,35 +218,30 @@ npm run build
# → Результат: dist/index.html (пустой шаблон)
```
#### 🚀 Production сборка (с SSG):
#### 🚀 Production сборка (с SSR):
```bash
npm run build:prod
# → Webpack в production режиме
# → Минификация
# → Автоматический SSG (prerender-multi.js)
# → Автоматический SSR (ssr-render.js)
# → Рендер реальных React компонентов через react-dom/server
# → Результат:
# - dist/index.html (со статическим контентом)
# - dist/terms.html (полное соглашение для SEO)
# - dist/index.html (UnderConstruction компонент)
# - dist/terms.html (Terms компонент с Chakra UI)
```
Вывод:
```
✅ Сборка успешно завершена!
🚀 Начинаем мульти-страничный пре-рендеринг...
index.html обновлен
📝 Генерируем полный HTML из terma.md...
terms.html создан с полным контентом
🎉 Пре-рендеринг завершен успешно!
```
#### 🔄 Production сборка (альтернативный SSR):
```bash
npm run build:prod:ssr
# → Использует ssr-prerender.js
# → SSR с jsdom окружением
# → Результат аналогичен build:prod
🚀 Запуск SSR с рендерингом React компонентов...
Компоненты загружены
✅ Компоненты отрендерены
index.html обновлен с SSR контентом
✅ terms.html создан с SSR контентом
🎉 SSR завершен успешно!
📄 Созданы: index.html, terms.html
💡 Весь контент отрендерен через React SSR
```
### Другие команды:
@@ -267,12 +276,15 @@ npm run test # Запустить тесты
- **@brojs/cli 1.9.5** - сборщик (обертка над webpack)
- **Webpack 5** - бандлер
- **Babel** - транспиляция
- **jsdom** - SSR окружение
- **@babel/register** - транспиляция TSX в Node.js
- **@babel/preset-react** - JSX поддержка
- **@babel/preset-typescript** - TypeScript поддержка
- **jsdom 25.x** - DOM эмуляция для SSR
- **canvas 3.x** - Canvas API для Lottie в SSR
### Дополнительно:
- **Lottie React** - анимации
- **Lottie React** - анимации (работает в SSR!)
- **Day.js** - работа с датами
- **ESLint** - линтинг
- **Prettier** - форматирование