-
Notifications
You must be signed in to change notification settings - Fork 10
/
Copy pathserver.tsx
66 lines (55 loc) · 1.53 KB
/
server.tsx
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
import Koa from 'koa';
import Router from 'koa-router';
import serve from 'koa-static';
import path from 'path';
import ReactDOMServer from 'react-dom/server';
import { StaticRouter } from 'react-router-dom/server';
import App from './src/App';
import Html from './src/components/Html';
const ABORT_DELAY = 10000;
const app = new Koa();
app.use(serve(path.join(__dirname, '/public')));
if (process.env.NODE_ENV === 'development') {
app.use(serve(path.join(__dirname, '/.parcel')));
}
const router = new Router();
async function render(ctx: Koa.Context) {
let didError = false;
/**
* NOTE: use promise to force koa waiting for streaming.
*/
return new Promise((_resolve, reject) => {
const stream = ReactDOMServer.renderToPipeableStream(
<StaticRouter location={ctx.url}>
<Html title="React SSR Demo">
<App />
</Html>
</StaticRouter>,
{
bootstrapScripts: ['/index.js'],
onShellReady() {
ctx.respond = false;
ctx.res.statusCode = didError ? 500 : 200;
ctx.response.set('content-type', 'text/html');
stream.pipe(ctx.res);
},
onError() {
didError = true;
reject();
},
},
);
setTimeout(() => {
stream.abort();
reject();
}, ABORT_DELAY);
});
}
router.get('(.*)', async (ctx) => {
await render(ctx);
});
app.use(router.routes());
const port = process.env.PORT || 3000;
app.listen(port, () => {
console.log(`🚀 Koa server is running at http://localhost:${port}`);
});