Files
pushkinohistory-ru-v2/scripts/prerender.js

54 lines
1.7 KiB
JavaScript

import fs from 'node:fs';
import path from 'node:path';
import http from 'node:http';
import { fileURLToPath } from 'node:url';
import express from 'express';
import puppeteer from 'puppeteer';
const __dirname = path.dirname(fileURLToPath(import.meta.url));
const ROOT = path.resolve(__dirname, '..');
const DIST = path.join(ROOT, 'dist');
const routes = JSON.parse(fs.readFileSync(path.join(DIST, 'routes.json'), 'utf8'));
const app = express();
app.use(express.static(DIST));
app.get('*', (_req, res) => res.sendFile(path.join(DIST, 'index.html')));
const server = http.createServer(app);
async function start() {
await new Promise((resolve) => server.listen(0, resolve));
const port = server.address().port;
const baseUrl = `http://127.0.0.1:${port}`;
const launchOpts = { headless: 'new', args: ['--no-sandbox', '--disable-setuid-sandbox'] };
if (process.env.PUPPETEER_EXECUTABLE_PATH) {
launchOpts.executablePath = process.env.PUPPETEER_EXECUTABLE_PATH;
}
const browser = await puppeteer.launch(launchOpts);
for (const route of routes) {
const page = await browser.newPage();
const url = `${baseUrl}${route}`;
try {
await page.goto(url, { waitUntil: 'networkidle0', timeout: 15000 });
} catch (e) {
console.warn(`prerender warn ${route}: ${e.message}`);
}
const html = await page.content();
const outDir = path.join(DIST, route);
fs.mkdirSync(outDir, { recursive: true });
fs.writeFileSync(path.join(outDir, 'index.html'), html);
console.log(`prerender: ${route}`);
await page.close();
}
await browser.close();
server.close();
}
start().catch((e) => {
console.error(e);
process.exit(1);
});