-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathserver.js
84 lines (74 loc) · 2.28 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
75
76
77
78
79
80
81
82
83
84
const fs = require('fs');
const Koa = require('koa');
const LRU = require('lru-cache');
const Router = require('@koa/router');
const serve = require('koa-static-server');
const devMiddleware = require('./lib/devMiddleware');
const { createBundleRenderer } = require('vue-server-renderer');
// SSR 相关
// server bundle 创建的 renderer 会自动将带有 hash 值文件名的js文件引入到 template 中
let renderer;
let template = fs.readFileSync('./src/template/index.html', 'utf8');
const isProd = process.env.NODE_ENV === 'production';
if (isProd) {
const serverBundle = require('./dist/vue-ssr-server-bundle.json');
const clientManifest = require('./dist/vue-ssr-client-manifest.json');
renderer = createBundleRenderer(serverBundle, {
runInNewContext: false,
clientManifest,
template,
});
}
// 开发模式下 renderer 相关交由 devMiddleware 编译处理
const render = {
template,
renderer,
};
// Server 相关
const app = new Koa();
const router = new Router();
const maxage = isProd ? 1000 * 60 : 0;// 浏览器最大缓存时间
const isCacheable = _ => isProd;
const microCache = new LRU({
max: 300,
maxAge: 1000,
stale: true //允许过期内容,减少请求峰值
});
// 开发模式下由 devMiddleware 提供打包文件
// serve will check if request path is allowed with rootPath
router.use('/dist', serve({ rootDir: './dist', rootPath: '/dist', maxage }));
// Render 相关路由
router.get('*', async (ctx, next) => {
await next();
ctx.body = ctx.state.html;
});
router.get('*', async ctx => {
const cacheable = isCacheable(ctx);
if (cacheable) {
const hit = microCache.get(ctx.url);
if (hit) {
return ctx.state.html = hit;
}
}
const context = { title: 'Hello SSR', url: ctx.url };
try {
const html = await render.renderer.renderToString(context);
if (cacheable) microCache.set(ctx.url, html);
ctx.state.html = html;
} catch (e) {
ctx.throw(e.code || 500);
console.error(e.message);
}
});
// 最后挂载通配符 * 路由
// 以让渲染文件请求通过 devMiddleware
const listen = () => {
app.use(router.routes());
app.use(router.allowedMethods());
app.listen(8080, () => {
console.log('Server running at localhost:8080');
});
};
isProd
? listen()
: devMiddleware(app, render).then(listen);