-
Notifications
You must be signed in to change notification settings - Fork 10
/
index.js
101 lines (86 loc) · 2.67 KB
/
index.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
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
import Koa from 'koa'
import serve from 'koa-static'
import mount from 'koa-mount'
import vsr from 'vue-server-renderer'
import { readFile } from 'fs/promises'
const { createBundleRenderer } = vsr
const serverBundle = JSON.parse(await readFile('./dist/vue-ssr-server-bundle.json'))
const clientManifest = JSON.parse(await readFile('./dist/vue-ssr-client-manifest.json'))
clientManifest.async = clientManifest.async.filter(file => !file.includes('.noinject.'))
const app = new Koa()
app.use(async (ctx, next) => {
try {
await next()
const { url, status } = ctx
if (status !== 200) {
return
}
if (url.includes('.hash.')) {
ctx.set('Cache-Control', 'public, max-age=31536000')
} else if (url.includes('/covers/')) {
ctx.set('Cache-Control', 'public, max-age=604800')
} else {
ctx.set('Cache-Control', 'max-age=14400')
}
} catch (e) {
if (e.status === 404) {
ctx.set('Cache-Control', 'no-cache')
}
}
})
const template = (await readFile('index.html', 'utf-8')).replace('<div id="app"></div>', '<!--vue-ssr-outlet-->')
const renderer = createBundleRenderer(serverBundle, {
runInNewContext: 'once',
template,
clientManifest
})
app.use(mount('/covers', serve('./src/covers')))
app.use(serve('dist'))
const langs = ['ChineseS', 'ChineseT', 'English', 'Japanese', 'Korean']
const themes = ['dark', 'light', 'auto']
app.use(async ctx => {
const queryLang = langs.includes(ctx.query.lang) ? ctx.query.lang : undefined
let lang = ctx.cookies.get('lang')
if (!lang) {
lang = queryLang || ctx.acceptsLanguages().reverse().reduce((p, l) => {
if (l.includes('Hant')) {
return 'ChineseT'
}
if (l.includes('CN') || l.includes('zh')) {
return 'ChineseS'
}
if (l.includes('en')) {
return 'English'
}
if (l.includes('JP') || l.includes('ja')) {
return 'Japanese'
}
if (l.includes('KR') || l.includes('ko')) {
return 'Korean'
}
return p
}, false) || 'English'
ctx.cookies.set('lang', lang, { httpOnly: false })
}
lang = queryLang || lang
const queryTheme = themes.includes(ctx.query.theme) ? ctx.query.theme : undefined
let theme = ctx.cookies.get('theme')
if (!theme) {
theme = queryTheme || themes[0]
ctx.cookies.set('theme', theme, { httpOnly: false })
}
theme = queryTheme || theme
if (ctx.url === '/index.html') {
ctx.url = '/'
}
let result = await renderer.renderToString({ url: ctx.url, lang, theme, fetch }).catch(e => {
console.error(e, { url: ctx.url })
if (e.code) {
ctx.throw(e.code)
}
return undefined
})
ctx.type = 'text/html'
ctx.body = result
})
app.listen(8300)