-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathserver.js
74 lines (65 loc) · 1.92 KB
/
server.js
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
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
import express from "express"
import portFinderSync from "portfinder-sync"
import { renderToPipeableStream } from "react-dom/server"
import { createServer } from "vite"
const port = portFinderSync.getPort(3000)
;(async () => {
/**
* Dev server
*
*
*/
async function createDevServer() {
const app = express()
// dev script to inject
const devScripts = {
js: [{ tag: "script", attr: { type: "module", src: "/src/index.tsx" } }],
}
// Create Vite server in middleware mode.
// This disables Vite's own HTML serving logic and let the parent server take control.
// https://vitejs.dev/config/server-options.html#server-middlewaremode
const vite = await createServer({
logLevel: "info",
server: {
middlewareMode: true,
},
appType: "custom",
})
// use vite's connect instance as middleware
app.use(vite.middlewares)
app.use("*", async (req, res, next) => {
if (req.originalUrl === "/favicon.ico") return
try {
// Transforms the ESM source code to be usable in Node.js
const { render } = await vite.ssrLoadModule(`src/server/index-server.tsx`)
// Get react-dom from the render method
const dom = await render(req.originalUrl, devScripts, false)
// Create stream to support Suspense API
const stream = renderToPipeableStream(dom, {
onShellReady() {
res.statusCode = 200
res.setHeader("Content-type", "text/html")
stream.pipe(res)
},
onError(e) {
res.statusCode = 500
console.error(e)
},
})
} catch (e) {
vite.ssrFixStacktrace(e)
next(e)
}
})
// return vite, app and server
return { vite, app }
}
/**
* Let's go!
*/
createDevServer().then(({ app }) =>
app.listen(port, () => {
console.log(`http://localhost:${port}`)
}),
)
})()