/* eslint-disable @typescript-eslint/no-require-imports */ /* eslint-disable no-undef */ // Настройка Babel для транспиляции TSX/JSX в Node.js require('@babel/register')({ extensions: ['.ts', '.tsx', '.js', '.jsx'], presets: [ '@babel/preset-env', '@babel/preset-react', '@babel/preset-typescript' ], ignore: [/node_modules/], cache: false }); const fs = require('fs'); const path = require('path'); const React = require('react'); const { renderToString } = require('react-dom/server'); const { Window } = require('happy-dom'); const { createCanvas } = require('canvas'); // Читаем index.ejs как основу для SSR const ejsTemplatePath = path.resolve(__dirname, '../src/index.ejs'); const ejsTemplate = fs.readFileSync(ejsTemplatePath, 'utf-8'); // Настройка полноценного DOM окружения через happy-dom на основе index.ejs const window = new Window({ url: 'http://localhost', width: 1024, height: 768 }); const document = window.document; document.write(ejsTemplate); // Расширяем happy-dom canvas поддержкой window.HTMLCanvasElement.prototype.getContext = function() { return createCanvas(200, 200).getContext('2d'); }; global.window = window; global.document = document; global.navigator = window.navigator; global.HTMLElement = window.HTMLElement; global.SVGElement = window.SVGElement; console.log('🚀 Запуск SSR с рендерингом React компонентов...'); try { // Импортируем компоненты const { UnderConstruction } = require('../src/pages/under-construction/underConstruction.tsx'); const { Terms } = require('../src/pages/terms/Terms.tsx'); const { ChakraProvider, extendTheme } = require('@chakra-ui/react'); console.log('✅ Компоненты загружены'); // Функция для рендера с Chakra UI + базовыми стилями function renderWithStyles(Component) { // Chakra theme с базовыми стилями const theme = extendTheme({}); // Генерируем базовые CSS переменные и стили Chakra const baseStyles = ` `; const html = renderToString( React.createElement( ChakraProvider, { theme, cssVarsRoot: 'body' }, React.createElement(Component) ) ); return { html, styles: baseStyles }; } // Рендерим компоненты с извлечением стилей const { html: homeContent, styles: homeStyles } = renderWithStyles(UnderConstruction); const { html: termsContent, styles: termsStyles } = renderWithStyles(Terms); console.log('✅ Компоненты отрендерены с Chakra UI + Emotion стилями'); // Читаем dist/index.html const distPath = path.resolve(__dirname, '../dist'); const indexPath = path.join(distPath, 'index.html'); let indexHtml = fs.readFileSync(indexPath, 'utf-8'); // 1. Главная страница const searchString = '
'; if (indexHtml.includes(searchString)) { indexHtml = indexHtml .replace(searchString, `
${homeContent}
`) .replace('', `${homeStyles}`); fs.writeFileSync(indexPath, indexHtml, 'utf-8'); console.log('✅ index.html обновлен с SSR контентом и стилями'); } // 2. Страница terms let termsHtml = indexHtml .replace(homeContent, termsContent) .replace(homeStyles, termsStyles) .replace('bro-js admin', 'Пользовательское соглашение - BROJS.RU') .replace( '', '' ); const termsPath = path.join(distPath, 'terms.html'); fs.writeFileSync(termsPath, termsHtml, 'utf-8'); console.log('✅ terms.html создан с SSR контентом и стилями'); console.log('🎉 SSR завершен успешно!'); console.log('📄 Созданы: index.html, terms.html'); console.log('💡 Весь контент отрендерен через React SSR'); console.log('🎨 Критические стили Emotion встроены в HTML'); } catch (error) { console.error('❌ Ошибка при SSR:', error.message); console.error(error.stack); process.exit(1); }