208 lines
6.6 KiB
JavaScript
208 lines
6.6 KiB
JavaScript
require("@babel/register")({
|
|
presets: [
|
|
["@babel/preset-env", { targets: { node: "current" } }],
|
|
"@babel/preset-react",
|
|
],
|
|
extensions: [".js", ".jsx"],
|
|
ignore: [/node_modules/],
|
|
});
|
|
|
|
// Minimal globals for socket.io-client only - no JSDOM to avoid interference
|
|
global.window = {}; // Minimal window object for productCache
|
|
global.navigator = { userAgent: "node.js" };
|
|
global.URL = require("url").URL;
|
|
global.Blob = class MockBlob {
|
|
constructor(data, options) {
|
|
this.data = data;
|
|
this.type = options?.type || "";
|
|
}
|
|
};
|
|
|
|
// Import modules
|
|
const fs = require("fs");
|
|
const path = require("path");
|
|
const React = require("react");
|
|
const io = require("socket.io-client");
|
|
|
|
// Initialize i18n for prerendering with German as default
|
|
const i18n = require("i18next");
|
|
const { initReactI18next } = require("react-i18next");
|
|
|
|
// Import translation (just German for testing)
|
|
const translationDE = require("./src/i18n/locales/de/translation.js").default;
|
|
|
|
// Initialize i18n
|
|
i18n
|
|
.use(initReactI18next)
|
|
.init({
|
|
resources: {
|
|
de: { translation: translationDE }
|
|
},
|
|
lng: 'de',
|
|
fallbackLng: 'de',
|
|
debug: false,
|
|
interpolation: {
|
|
escapeValue: false
|
|
},
|
|
react: {
|
|
useSuspense: false
|
|
}
|
|
});
|
|
|
|
// Make i18n available globally
|
|
global.i18n = i18n;
|
|
|
|
// Import prerender modules
|
|
const config = require("./prerender/config.cjs");
|
|
const shopConfig = require("./src/config.js").default;
|
|
const { renderPage } = require("./prerender/renderer.cjs");
|
|
const { generateProductMetaTags, generateProductJsonLd } = require("./prerender/seo.cjs");
|
|
const { fetchProductDetails, saveProductImages } = require("./prerender/data-fetching.cjs");
|
|
|
|
// Import product component
|
|
const PrerenderProduct = require("./src/PrerenderProduct.js").default;
|
|
|
|
const renderSingleProduct = async (productSeoName) => {
|
|
const socketUrl = "http://127.0.0.1:9303";
|
|
console.log(`🔌 Connecting to socket at ${socketUrl}...`);
|
|
|
|
const socket = io(socketUrl, {
|
|
path: "/socket.io/",
|
|
transports: ["websocket"],
|
|
reconnection: false,
|
|
timeout: 10000,
|
|
});
|
|
|
|
return new Promise((resolve, reject) => {
|
|
const timeout = setTimeout(() => {
|
|
console.error("❌ Timeout: Could not connect to backend after 15 seconds");
|
|
socket.disconnect();
|
|
reject(new Error("Connection timeout"));
|
|
}, 15000);
|
|
|
|
socket.on("connect", async () => {
|
|
console.log(`✅ Socket connected. Fetching product: ${productSeoName}`);
|
|
|
|
try {
|
|
// Fetch product details
|
|
const productDetails = await fetchProductDetails(socket, productSeoName);
|
|
console.log(`📦 Product found: ${productDetails.product.name}`);
|
|
|
|
// Save product image to static files
|
|
if (productDetails.product) {
|
|
console.log(`📷 Saving product image...`);
|
|
await saveProductImages(socket, [productDetails.product], "Single Product", config.outputDir);
|
|
}
|
|
|
|
// Set up minimal global cache (empty for single product test)
|
|
global.window.productCache = {};
|
|
global.productCache = {};
|
|
|
|
// Create product component
|
|
const productComponent = React.createElement(PrerenderProduct, {
|
|
productData: productDetails,
|
|
t: global.i18n.t.bind(global.i18n),
|
|
});
|
|
|
|
// Generate metadata
|
|
const actualSeoName = productDetails.product.seoName || productSeoName;
|
|
const filename = `Artikel/${actualSeoName}`;
|
|
const location = `/Artikel/${actualSeoName}`;
|
|
const description = `Product "${productDetails.product.name}" (seoName: ${productSeoName})`;
|
|
|
|
const metaTags = generateProductMetaTags({
|
|
...productDetails.product,
|
|
seoName: actualSeoName,
|
|
}, shopConfig.baseUrl, shopConfig);
|
|
|
|
const jsonLdScript = generateProductJsonLd({
|
|
...productDetails.product,
|
|
seoName: actualSeoName,
|
|
}, shopConfig.baseUrl, shopConfig);
|
|
|
|
const combinedMetaTags = metaTags + "\n" + jsonLdScript;
|
|
|
|
// Render the page
|
|
console.log(`🎨 Rendering product page...`);
|
|
const success = renderPage(
|
|
productComponent,
|
|
location,
|
|
filename,
|
|
description,
|
|
combinedMetaTags,
|
|
true, // needsRouter
|
|
config,
|
|
false, // suppressLogs
|
|
productDetails // productData for cache
|
|
);
|
|
|
|
if (success) {
|
|
const outputPath = path.resolve(__dirname, config.outputDir, `${filename}.html`);
|
|
console.log(`✅ Product page rendered successfully!`);
|
|
console.log(`📄 Output file: ${outputPath}`);
|
|
console.log(`🌐 Test URL: http://localhost:3000/Artikel/${actualSeoName}`);
|
|
|
|
// Show file size
|
|
if (fs.existsSync(outputPath)) {
|
|
const stats = fs.statSync(outputPath);
|
|
console.log(`📊 File size: ${Math.round(stats.size / 1024)}KB`);
|
|
}
|
|
} else {
|
|
console.log(`❌ Failed to render product page`);
|
|
}
|
|
|
|
clearTimeout(timeout);
|
|
socket.disconnect();
|
|
resolve(success);
|
|
|
|
} catch (error) {
|
|
console.error(`❌ Error fetching/rendering product: ${error.message}`);
|
|
clearTimeout(timeout);
|
|
socket.disconnect();
|
|
reject(error);
|
|
}
|
|
});
|
|
|
|
socket.on("connect_error", (err) => {
|
|
clearTimeout(timeout);
|
|
console.error("❌ Socket connection error:", err);
|
|
console.log("💡 Make sure the backend server is running on http://127.0.0.1:9303");
|
|
reject(err);
|
|
});
|
|
|
|
socket.on("error", (err) => {
|
|
clearTimeout(timeout);
|
|
console.error("❌ Socket error:", err);
|
|
reject(err);
|
|
});
|
|
});
|
|
};
|
|
|
|
// Get product seoName from command line arguments
|
|
const productSeoName = process.argv[2];
|
|
|
|
if (!productSeoName) {
|
|
console.log("❌ Usage: node prerender-single-product.cjs <product-seo-name>");
|
|
console.log("📝 Example: node prerender-single-product.cjs led-grow-light-600w");
|
|
process.exit(1);
|
|
}
|
|
|
|
console.log(`🚀 Starting single product prerender test...`);
|
|
console.log(`🎯 Product SEO name: ${productSeoName}`);
|
|
console.log(`🔧 Mode: ${config.isProduction ? 'PRODUCTION' : 'DEVELOPMENT'}`);
|
|
console.log(`📁 Output directory: ${config.outputDir}`);
|
|
|
|
renderSingleProduct(productSeoName)
|
|
.then((success) => {
|
|
if (success) {
|
|
console.log(`\n🎉 Single product prerender completed successfully!`);
|
|
process.exit(0);
|
|
} else {
|
|
console.log(`\n💥 Single product prerender failed!`);
|
|
process.exit(1);
|
|
}
|
|
})
|
|
.catch((error) => {
|
|
console.error(`\n💥 Single product prerender failed:`, error.message);
|
|
process.exit(1);
|
|
});
|