PozoAppNov266pm/scripts/jsx-to-html-converter.js

140 lines
4.5 KiB
JavaScript
Raw Permalink Normal View History

#!/usr/bin/env node
import { execSync, spawn } from 'child_process';
import { setTimeout } from 'timers/promises';
import fs from 'fs';
import path from 'path';
const isWin = process.platform === 'win32';
const npmCmd = isWin ? 'npm.cmd' : 'npm';
const npxCmd = isWin ? 'npx.cmd' : 'npx';
if (!process.env.SKIP_BUILD) {
console.log('Building the React app...');
try {
execSync(`${npmCmd} run build`, { stdio: 'inherit', shell: isWin });
} catch (error) {
console.error('Build failed:', error.message);
process.exit(1);
}
} else {
console.log('Skipping build (SKIP_BUILD=1)');
}
// Copy server.js and server folder to dist for iisnode
console.log('Copying server files to dist...');
try {
// Create dist-specific server.js for iisnode (serves from __dirname, not dist subfolder)
const distServerJs = `import express from 'express';
import path from 'path';
import { fileURLToPath } from 'url';
import seoMiddleware from './server/seo-middleware.js';
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const app = express();
const PORT = process.env.PORT || 3000;
// Configure MIME types for JSX files
app.use((req, res, next) => {
if (req.path.endsWith('.jsx')) {
res.setHeader('Content-Type', 'application/javascript');
}
next();
});
// Serve static assets FIRST (CSS, JS, images, fonts) - these MUST work
app.use('/assets', express.static(path.join(__dirname, 'assets')));
app.use('/src', express.static(path.join(__dirname, '../src')));
app.use('/og', express.static(path.join(__dirname, 'og')));
app.use(express.static(__dirname, {
index: false, // Don't serve index.html automatically
setHeaders: (res, filePath) => {
// Only block HTML files - let everything else through
if (filePath.endsWith('.html')) {
res.status(404).end();
return;
}
}
}));
// CRITICAL: Apply SEO middleware AFTER static files
// This ensures HTML requests go through SEO middleware
// But static assets are served first
app.use(seoMiddleware);
app.listen(PORT, () => {
console.log(\`Server running on port \${PORT}\`);
console.log('Dynamic SEO enabled!');
});
export default app;
`;
fs.writeFileSync(path.join('dist', 'server.js'), distServerJs, 'utf8');
// Copy server folder to dist
if (!fs.existsSync(path.join('dist', 'server'))) {
fs.mkdirSync(path.join('dist', 'server'));
}
// Copy server.js from server folder (if it exists)
if (fs.existsSync(path.join('server', 'server.js'))) {
fs.copyFileSync(
path.join('server', 'server.js'),
path.join('dist', 'server', 'server.js')
);
}
// Create dist-specific seo-middleware.js with correct paths
const seoMiddlewareJs = fs.readFileSync(path.join('server', 'seo-middleware.js'), 'utf8');
// Replace the path from ../dist to .. for dist deployment (handle all variations)
const distSeoMiddlewareJs = seoMiddlewareJs
.replace(/path\.join\(__dirname, '\.\.\/dist'/g, "path.join(__dirname, '..'")
.replace(/path\.join\(__dirname, '\.\.', 'dist'/g, "path.join(__dirname, '..'")
.replace(/path\.join\(__dirname, '\.\.\/dist',/g, "path.join(__dirname, '..',")
.replace(/path\.join\(__dirname, '\.\.\/dist"/g, "path.join(__dirname, '..\"")
.replace(/path\.join\(__dirname, '\.\.\/dist',\s*req\.path/g, "path.join(__dirname, '..', req.path");
fs.writeFileSync(path.join('dist', 'server', 'seo-middleware.js'), distSeoMiddlewareJs, 'utf8');
console.log('Server files copied successfully!');
} catch (error) {
console.error('Failed to copy server files:', error.message);
process.exit(1);
}
if (process.env.PRERENDER === '1') {
let server;
try {
console.log('Starting development server for prerender...');
server = spawn(npmCmd, ['run', 'dev'], { stdio: 'inherit', shell: isWin });
// Wait for server to start
await setTimeout(5000);
console.log('Prerendering pages with react-snap...');
execSync(`${npxCmd} react-snap`, { stdio: 'inherit', shell: isWin });
} catch (error) {
console.warn('Prerendering skipped due to error (continuing to SEO):', error?.message || error);
} finally {
if (server) {
console.log('Stopping development server...');
server.kill();
}
}
} else {
console.log('Skipping react-snap prerender (set PRERENDER=1 to enable)');
}
console.log('Applying SEO optimizations...');
try {
execSync('node scripts/generate-seo.js', { stdio: 'inherit', shell: isWin });
} catch (error) {
console.error('SEO application failed:', error.message);
process.exit(1);
}
console.log('JSX to HTML conversion completed successfully!');