127 lines
4.0 KiB
JavaScript
127 lines
4.0 KiB
JavaScript
#!/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;
|
|
|
|
// Redirect /home to root
|
|
app.use((req, res, next) => {
|
|
if (req.path.startsWith('/home')) {
|
|
const newPath = req.path.replace('/home', '') || '/';
|
|
return res.redirect(301, newPath);
|
|
}
|
|
next();
|
|
});
|
|
|
|
// Serve static files - __dirname is already dist/
|
|
app.use(express.static(__dirname));
|
|
|
|
// Apply SEO middleware only for unmatched GET requests
|
|
app.get('*', 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!');
|