Skip to content

Commit 28e723b

Browse files
authored
chore(rsc): rework ssg example (#713)
1 parent fc8c1d7 commit 28e723b

File tree

3 files changed

+46
-22
lines changed

3 files changed

+46
-22
lines changed

packages/plugin-rsc/examples/ssg/src/framework/entry.rsc.tsx

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,3 +36,27 @@ export default async function handler(request: Request): Promise<Response> {
3636
},
3737
})
3838
}
39+
40+
// return both rsc and html streams at once for ssg
41+
export async function handleSsg(request: Request): Promise<{
42+
html: ReadableStream<Uint8Array>
43+
rsc: ReadableStream<Uint8Array>
44+
}> {
45+
const url = new URL(request.url)
46+
const rscPayload: RscPayload = { root: <Root url={url} /> }
47+
const rscStream = ReactServer.renderToReadableStream<RscPayload>(rscPayload)
48+
const [rscStream1, rscStream2] = rscStream.tee()
49+
50+
const ssr = await import.meta.viteRsc.loadModule<
51+
typeof import('./entry.ssr')
52+
>('ssr', 'index')
53+
const htmlStream = await ssr.renderHtml(rscStream1, {
54+
ssg: true,
55+
})
56+
57+
return { html: htmlStream, rsc: rscStream2 }
58+
}
59+
60+
if (import.meta.hot) {
61+
import.meta.hot.accept()
62+
}

packages/plugin-rsc/examples/ssg/src/framework/entry.ssr.tsx

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,12 @@ import * as ReactDomServer from 'react-dom/server.edge'
44
import { injectRSCPayload } from 'rsc-html-stream/server'
55
import type { RscPayload } from './shared'
66

7-
export async function renderHtml(rscStream: ReadableStream<Uint8Array>) {
7+
export async function renderHtml(
8+
rscStream: ReadableStream<Uint8Array>,
9+
options?: {
10+
ssg?: boolean
11+
},
12+
) {
813
const [rscStream1, rscStream2] = rscStream.tee()
914

1015
let payload: Promise<RscPayload>
@@ -20,8 +25,9 @@ export async function renderHtml(rscStream: ReadableStream<Uint8Array>) {
2025
const htmlStream = await ReactDomServer.renderToReadableStream(<SsrRoot />, {
2126
bootstrapScriptContent,
2227
})
23-
// for SSG
24-
await htmlStream.allReady
28+
if (options?.ssg) {
29+
await htmlStream.allReady
30+
}
2531

2632
let responseStream: ReadableStream<Uint8Array> = htmlStream
2733
responseStream = responseStream.pipeThrough(injectRSCPayload(rscStream2))

packages/plugin-rsc/examples/ssg/vite.config.ts

Lines changed: 13 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import assert from 'node:assert'
21
import fs from 'node:fs'
32
import path from 'node:path'
43
import { Readable } from 'node:stream'
@@ -60,29 +59,24 @@ async function renderStatic(config: ResolvedConfig) {
6059

6160
// render rsc and html
6261
const baseDir = config.environments.client.build.outDir
63-
for (const htmlPath of staticPaths) {
64-
config.logger.info('[vite-rsc:ssg] -> ' + htmlPath)
65-
const rscPath = htmlPath + RSC_POSTFIX
66-
const htmlResponse = await entry.default(
67-
new Request(new URL(htmlPath, 'http://ssg.local')),
62+
for (const staticPatch of staticPaths) {
63+
config.logger.info('[vite-rsc:ssg] -> ' + staticPatch)
64+
const { html, rsc } = await entry.handleSsg(
65+
new Request(new URL(staticPatch, 'http://ssg.local')),
6866
)
69-
assert.equal(htmlResponse.status, 200)
70-
await fs.promises.writeFile(
71-
path.join(baseDir, normalizeHtmlFilePath(htmlPath)),
72-
Readable.fromWeb(htmlResponse.body as any),
73-
)
74-
75-
const rscResponse = await entry.default(
76-
new Request(new URL(rscPath, 'http://ssg.local')),
77-
)
78-
assert.equal(rscResponse.status, 200)
79-
await fs.promises.writeFile(
80-
path.join(baseDir, rscPath),
81-
Readable.fromWeb(rscResponse.body as any),
67+
await writeFileStream(
68+
path.join(baseDir, normalizeHtmlFilePath(staticPatch)),
69+
html,
8270
)
71+
await writeFileStream(path.join(baseDir, staticPatch + RSC_POSTFIX), rsc)
8372
}
8473
}
8574

75+
async function writeFileStream(filePath: string, stream: ReadableStream) {
76+
await fs.promises.mkdir(path.dirname(filePath), { recursive: true })
77+
await fs.promises.writeFile(filePath, Readable.fromWeb(stream as any))
78+
}
79+
8680
function normalizeHtmlFilePath(p: string) {
8781
if (p.endsWith('/')) {
8882
return p + 'index.html'

0 commit comments

Comments
 (0)