-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathprerender.ts
More file actions
50 lines (39 loc) · 1.54 KB
/
Copy pathprerender.ts
File metadata and controls
50 lines (39 loc) · 1.54 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
/**
* Build-time prerender (SSG) step.
*
* Runs after both the client build (`vite build`) and the server build
* (`vite build --ssr src/entry-server.tsx`). It renders the app to an HTML
* string and injects it into the client-built `index.html`, producing a fully
* static, pre-rendered page that hydrates on the client.
*/
import { readFileSync, rmSync, writeFileSync } from 'node:fs';
import { dirname, resolve } from 'node:path';
import { fileURLToPath, pathToFileURL } from 'node:url';
const __dirname = dirname(fileURLToPath(import.meta.url));
const distDir = resolve(__dirname, 'dist');
const templatePath = resolve(distDir, 'index.html');
const serverEntryPath = resolve(distDir, 'server/entry-server.js');
const serverDir = resolve(distDir, 'server');
const PLACEHOLDER = '<!--ssr-outlet-->';
async function prerender() {
const template = readFileSync(templatePath, 'utf-8');
if (!template.includes(PLACEHOLDER)) {
throw new Error(
`Could not find "${PLACEHOLDER}" in dist/index.html. Is the placeholder still in index.html?`,
);
}
const { render } = await import(pathToFileURL(serverEntryPath).href) as {
render: () => string;
};
const appHtml = render();
const html = template.replace(PLACEHOLDER, appHtml);
writeFileSync(templatePath, html);
// The server bundle is only needed for prerendering; keep it out of the
// deployed output.
rmSync(serverDir, { recursive: true, force: true });
console.log('Prerendered dist/index.html');
}
prerender().catch(err => {
console.error(err);
process.exit(1);
});