-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathserver.ts
130 lines (108 loc) · 3.6 KB
/
server.ts
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
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
/// <reference types="./typings/index" />
/// <reference types="./typings/typing" />
import './env';
import next from 'next';
import express, { Request, Response } from 'express';
import { enableStaticRendering } from 'mobx-react';
import path from 'path';
import helmet from 'helmet';
import cookieParser from 'cookie-parser';
import responseTime from 'response-time';
import proxy from 'http-proxy-middleware';
import LRUCache from 'lru-cache';
import { LocaleTypeValues, LocaleType } from '@common/enum/locale';
import { routeObject } from './lib/routeObject';
const dev = process.env.NODE_ENV !== 'production';
// const dev = false;
const app = next({ dev, quiet: false });
const handle = app.getRequestHandler();
// eslint-disable-next-line react-hooks/rules-of-hooks
enableStaticRendering(true);
const tranLocate = (value: string) => value.replace(/_/g, '-').replace(/\s/g, '').toLowerCase().split(',')[0];
const ssrCache = new LRUCache({
max: 1000, // cache item count
// maxAge: 1000 * 60 * 60, // 1hour
maxAge: 1000 * 30, // 30 ses
});
app.prepare().then(() => {
const server = express();
server.use(helmet({
contentSecurityPolicy: false,
}));
server.use(cookieParser());
server.use(responseTime());
server.use(express.static('public'));
server.use((req: any, res: any, nextCb) => {
const header = req.get('accept-language');
const cookie = req.cookies.locate;
const acceptedLanguages = (cookie || header || '').split(';');
const headerLocate = tranLocate(cookie || acceptedLanguages[0]) as LocaleType;
if (LocaleTypeValues.includes(headerLocate)) {
req.locale = headerLocate;
} else {
req.locale = LocaleType['zh-CN'];
}
nextCb();
});
server.get('/_next/*', (req, res) => {
/* serving _next static content using next.js handler */
handle(req, res);
});
server.get('/service-worker.js', (req, res) => {
const data = path.join(process.cwd(), '.next', 'service-worker.js');
res.sendFile(data);
});
// eslint-disable-next-line no-restricted-syntax
for (const key in routeObject) {
if (key) {
server.get(key, (req: Request, res: Response) => app.render(req, res, `/${routeObject[key]}`, req.query as any));
}
}
if (dev) {
server.use(
'/api',
proxy({ target: process.env.SERVER_URL, changeOrigin: true }),
);
server.use(
'/oauth',
proxy({ target: process.env.SERVER_URL, changeOrigin: true }),
);
server.use(
'/graphql',
proxy({ target: process.env.SERVER_URL, changeOrigin: true }),
);
server.use(
'/socket.io',
proxy({ target: process.env.SERVER_URL, changeOrigin: true }),
);
}
server.get('*', (req, res) => handle(req, res));
server.listen(process.env.PAGE_PORT, () => {
console.log(`> Ready on http://localhost:${process.env.PAGE_PORT}`);
});
});
const getCacheKey = (req: any) => `${req.url}`;
async function renderAndCache(req: any, res: any, pagePath: any, queryParams: any) {
const key = getCacheKey(req);
// If we have a page in the cache, let's serve it
if (ssrCache.has(key)) {
res.setHeader('x-cache', 'HIT');
res.send(ssrCache.get(key));
return;
}
try {
// If not let's render the page into HTML
const html = await app.renderToHTML(req, res, pagePath, queryParams);
// Something is wrong with the request, let's skip the cache
if (res.statusCode !== 200) {
res.send(html);
return;
}
// Let's cache this page
ssrCache.set(key, html);
res.setHeader('x-cache', 'MISS');
res.send(html);
} catch (err) {
app.renderError(err, req, res, pagePath, queryParams);
}
}