You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
121 lines
3.7 KiB
121 lines
3.7 KiB
// server.js
|
|
const express = require('express')
|
|
const path = require('path')
|
|
const fs = require('fs')
|
|
const LRU = require('lru-cache')
|
|
const microcache = require('route-cache')
|
|
const compression = require('compression')
|
|
const resolve = file => path.resolve(__dirname, file)
|
|
|
|
const { createBundleRenderer } = require('vue-server-renderer')
|
|
|
|
const { isProd } = require("./build/util");
|
|
const useMicroCache = process.env.MICRO_CACHE !== 'false'
|
|
|
|
const serverInfo =
|
|
`express/${require('express/package.json').version} ` +
|
|
`vue-server-renderer/${require('vue-server-renderer/package.json').version}`
|
|
|
|
const app = express()
|
|
|
|
function createRenderer (bundle, options) {
|
|
// https://github.com/vuejs/vue/blob/dev/packages/vue-server-renderer/README.md#why-use-bundlerenderer
|
|
return createBundleRenderer(bundle, Object.assign(options, {
|
|
// for component caching
|
|
// cache: LRU({
|
|
// max: 1000,
|
|
// maxAge: 1000 * 60 * 15
|
|
// }),
|
|
// this is only needed when vue-server-renderer is npm-linked
|
|
basedir: resolve('./dist'),
|
|
// recommended for performance
|
|
runInNewContext: false
|
|
}))
|
|
}
|
|
|
|
|
|
let renderer
|
|
let readyPromise
|
|
const templatePath = resolve('./src/index.template.html')
|
|
if (isProd) {
|
|
// In production: create server renderer using template and built server bundle.
|
|
// The server bundle is generated by vue-ssr-webpack-plugin.
|
|
const template = fs.readFileSync(templatePath, 'utf-8')
|
|
const bundle = require('./dist/vue-ssr-server-bundle.json')
|
|
// The client manifests are optional, but it allows the renderer
|
|
// to automatically infer preload/prefetch links and directly add <script>
|
|
// tags for any async chunks used during render, avoiding waterfall requests.
|
|
const clientManifest = require('./dist/vue-ssr-client-manifest.json')
|
|
renderer = createRenderer(bundle, {
|
|
template,
|
|
clientManifest
|
|
})
|
|
}else{
|
|
readyPromise = require('./build/setup-dev-server')(
|
|
app,
|
|
templatePath,
|
|
(bundle, options) => {
|
|
renderer = createRenderer(bundle, options)
|
|
}
|
|
)
|
|
}
|
|
|
|
const serve = (path, cache) => express.static(resolve(path), {
|
|
maxAge: cache && isProd ? 1000 * 60 * 60 * 24 * 30 : 0
|
|
})
|
|
|
|
app.use(compression({ threshold: 0 }))
|
|
app.use('/dist', serve('./dist', true))
|
|
app.use('/public', serve('./public', true))
|
|
app.use('/manifest.json', serve('./manifest.json', true))
|
|
app.use('/service-worker.js', serve('./dist/service-worker.js'))
|
|
app.use(microcache.cacheSeconds(1, req => useMicroCache && req.originalUrl))
|
|
|
|
function render (req, res) {
|
|
const s = Date.now()
|
|
|
|
res.setHeader("Content-Type", "text/html")
|
|
res.setHeader("Server", serverInfo)
|
|
|
|
const handleError = err => {
|
|
if (err.url) {
|
|
res.redirect(err.url)
|
|
} else if(err.code === 404) {
|
|
res.status(404).send('404 | Page Not Found')
|
|
} else {
|
|
// Render Error Page or Redirect
|
|
res.status(500).send('500 | Internal Server Error')
|
|
console.error(`error during render : ${req.url}`)
|
|
console.error(err.stack)
|
|
}
|
|
}
|
|
const context = {
|
|
title: 'hsello',
|
|
meta: `
|
|
<meta charset="UTF-8">
|
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<meta name="keyword" content="vue,ssr">
|
|
<meta name="description" content="vue srr demo">
|
|
`,
|
|
url: req.url
|
|
}
|
|
renderer.renderToString(context, (err, html) => {
|
|
if (err) {
|
|
return handleError(err)
|
|
}
|
|
res.send(html)
|
|
if (!isProd) {
|
|
console.log(`whole request: ${Date.now() - s}ms`)
|
|
}
|
|
})
|
|
}
|
|
|
|
app.get('*', isProd ? render : (req, res) => {
|
|
readyPromise.then(() => render(req, res))
|
|
})
|
|
|
|
const port = process.env.PORT || 8080
|
|
app.listen(port, () => {
|
|
console.log(`server started at localhost:${port}`)
|
|
})
|
|
|