Vue-SSR-Koa2-Scaffold/config/ssr.js

101 lines
2.7 KiB
JavaScript
Raw Normal View History

2018-11-11 23:47:41 +08:00
const fs = require('fs')
const path = require('path')
const chalk = require('chalk')
const LRU = require('lru-cache')
const {
createBundleRenderer
} = require('vue-server-renderer')
const isProd = process.env.NODE_ENV === 'production'
const setUpDevServer = require('./setup-dev-server')
const HtmlMinifier = require('html-minifier').minify
const pathResolve = file => path.resolve(__dirname, file)
module.exports = app => {
return new Promise((resolve, reject) => {
const createRenderer = (bundle, options) => {
return createBundleRenderer(bundle, Object.assign(options, {
cache: LRU({
max: 1000,
maxAge: 1000 * 60 * 15
}),
basedir: pathResolve('../dist/web'),
runInNewContext: false
}))
}
let renderer = null
if (isProd) {
// prod mode
const template = HtmlMinifier(fs.readFileSync(pathResolve('../public/index.html'), 'utf-8'), {
collapseWhitespace: true,
removeAttributeQuotes: true,
removeComments: false
})
const bundle = require(pathResolve('../dist/web/vue-ssr-server-bundle.json'))
const clientManifest = require(pathResolve('../dist/web/vue-ssr-client-manifest.json'))
renderer = createRenderer(bundle, {
template,
clientManifest
})
} else {
// dev mode
setUpDevServer(app, (bundle, options, apiMain, apiOutDir) => {
try {
const API = eval(apiMain).default // eslint-disable-line
const server = API(app)
renderer = createRenderer(bundle, options)
resolve(server)
} catch (e) {
console.log(chalk.red('\nServer error'), e)
}
})
}
2018-11-11 23:47:41 +08:00
app.use(async (ctx, next) => {
if (!renderer) {
ctx.type = 'html'
ctx.body = 'waiting for compilation... refresh in a moment.'
next()
return
}
let status = 200
let html = null
const context = {
url: ctx.url,
title: 'OK'
}
if (/^\/api/.test(ctx.url)) { // 如果请求以/api开头则进入api部分进行处理。
next()
return
}
try {
status = 200
html = await renderer.renderToString(context)
} catch (e) {
if (e.message === '404') {
status = 404
html = '404 | Not Found'
} else {
status = 500
console.log(chalk.red('\nError: '), e.message)
html = '500 | Internal Server Error'
}
}
ctx.type = 'html'
ctx.status = status || ctx.status
ctx.body = html
next()
})
if (isProd) {
const API = require('../dist/api/api').default
const server = API(app)
resolve(server)
}
2018-11-11 23:47:41 +08:00
})
}