исправил скрипт для пререндеринга, сделал получение страниц динамическим добавил гннерацию карты

This commit is contained in:
Joe_Peach committed 2026-04-12 16:12:43 +03:00
1 parent b7027d1183
commit c6b9001f74
1 file changed
+129 -52
+129 -52
View File
@@ -1,69 +1,146 @@
import { readFileSync, writeFileSync, mkdirSync, existsSync } from 'fs';
import { resolve, dirname } from 'path';
import { fileURLToPath } from 'url';
import { readFileSync, writeFileSync, mkdirSync, existsSync } from "fs";
import { resolve, dirname } from "path";
import { fileURLToPath } from "url";
import { client } from "../src/api/client";
const __dirname = dirname(fileURLToPath(import.meta.url));
// Список всех страниц
const routes = [
'/',
'/products',
'/about',
// добавьте свои URL
];
const products = async function getProducts() {
try {
console.log("📡 Загрузка товаров из API...");
const response = await client.get("/productList/");
return response.data;
} catch (error) {
console.error("❌ Ошибка загрузки из API:", error.message);
console.log("📦 Использую тестовые данные...");
}
};
const distPath = resolve(__dirname, '../dist');
const indexHtmlPath = resolve(distPath, 'index.html');
const distPath = resolve(__dirname, "../dist");
const indexHtmlPath = resolve(distPath, "index.html");
if (!existsSync(indexHtmlPath)) {
console.error('❌ Сначала запустите npm run build');
console.error("❌ Сначала запустите npm run build");
process.exit(1);
}
// Читаем исходный HTML
let baseHtml = readFileSync(indexHtmlPath, 'utf-8');
let baseHtml = readFileSync(indexHtmlPath, "utf-8");
// Добавляем базовые мета-теги для каждой страницы
const pages = {
'/': {
title: 'Магазин труб - Главная',
description: 'Купить канализационные трубы по низким ценам'
const pages = [
{
path: "/",
title: "Магазин труб - Главная",
description:
"Купить канализационные трубы, фитинги и комплектующие по низким ценам.",
},
'/products': {
title: 'Каталог труб для канализации',
description: 'Широкий выбор труб, фитингов и комплектующих'
{
path: "/products",
title: "Каталог труб и фитингов для канализации",
description:
"Широкий выбор канализационных труб ПВХ, фитингов, тройников, переходов, колен. Высокое качество, низкие цены.",
},
'/about': {
title: 'О магазине труб',
description: 'Информация о нашей компании'
}
};
{
path: "/about",
title: "О магазине труб - Доставка и гарантия",
description:
"Информация о нашей компании. Как мы работаем, условия доставки, гарантия на все товары.",
},
];
routes.forEach(route => {
const pageInfo = pages[route] || pages['/'];
// Заменяем мета-теги в HTML
let html = baseHtml
.replace(/<title>.*?<\/title>/, `<title>${pageInfo.title}</title>`)
.replace(
/<meta name="description".*?>/,
`<meta name="description" content="${pageInfo.description}">`
const allRoutes = [...pages];
// Добавляем маршруты товаров
for (const product of products) {
allRoutes.push({
path: `/product/${product.id}`,
description: product.description,
title: product.full_name,
});
}
let successCount = 0;
let errorCount = 0;
for (const route of allRoutes) {
try {
// Заменяем мета-теги
let html = baseHtml
.replace(
/<title>.*?<\/title>/,
`<title>${escapeHtml(route.title)}</title>`,
)
.replace(
/<meta name="description".*?>/,
`<meta name="description" content="${escapeHtml(route.description)}">`,
);
// Добавляем Open Graph теги (для соцсетей)
html = html.replace(
"</head>",
` <meta property="og:title" content="${escapeHtml(route.title)}">
<meta property="og:description" content="${escapeHtml(route.description)}">
<meta property="og:type" content="website">
<meta name="robots" content="index, follow">
</head>`,
);
// Определяем путь для сохранения
let outputPath;
if (route === '/') {
outputPath = indexHtmlPath;
} else {
const routeDir = resolve(distPath, route.substring(1));
if (!existsSync(routeDir)) {
mkdirSync(routeDir, { recursive: true });
}
outputPath = resolve(routeDir, 'index.html');
}
writeFileSync(outputPath, html);
console.log(`✅ ${route} → ${outputPath}`);
});
console.log('✨ Done!');
// Определяем путь для сохранения
let outputPath;
if (route.path === "/") {
outputPath = indexHtmlPath;
} else {
const routeDir = resolve(distPath, route.path.substring(1));
if (!existsSync(routeDir)) {
mkdirSync(routeDir, { recursive: true });
}
outputPath = resolve(routeDir, "index.html");
}
writeFileSync(outputPath, html);
console.log(`✅ ${route.path} → ${outputPath}`);
successCount++;
} catch (error) {
console.error(`❌ Ошибка при генерации ${route.path}:`, error.message);
errorCount++;
}
}
const urls = allRoutes.map(route => ({
url: route.path,
lastmod: new Date().toISOString().split('T')[0],
priority: route.path === '/' ? 1.0 : route.path.startsWith('/product') ? 0.8 : 0.7
}));
const sitemapContent = generateSitemap(urls, 'https://pvh.projects.rustprogersteam.ru'); // замените на ваш домен
const sitemapPath = resolve(distPath, 'sitemap.xml');
writeFileSync(sitemapPath, sitemapContent);
console.log(`\n🗺️ Sitemap создан: ${sitemapPath}`);
// ============================================
// ВСПОМОГАТЕЛЬНЫЕ ФУНКЦИИ
// ============================================
function escapeHtml(text) {
return text
.replace(/&/g, '&amp;')
.replace(/</g, '&lt;')
.replace(/>/g, '&gt;')
.replace(/"/g, '&quot;')
.replace(/'/g, '&#39;');
}
function generateSitemap(urls, baseUrl) {
return `<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
${urls.map(item => ` <url>
<loc>${baseUrl}${item.url}</loc>
<lastmod>${item.lastmod}</lastmod>
<priority>${item.priority}</priority>
</url>`).join('\n')}
</urlset>`;
}
console.log("✨ Done!");