详解Vue SSR( Vue2 + Koa2 + Webpack4)配置指南

2020-06-14 06:22:03易采站长站整理

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)
}
})
}

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)
}
})
}

这里新加入了 html-minifier 模块来压缩生产环境的 index.html 文件( yarn add html-minifier )。其余配置和官方给出的差不多,不再赘述。只不过Promise返回的是 require(‘http’).createServer(app.callback()) (详见源码)。这样做的目的是为了共用一个koa2实例。此外,这里拦截了 /api 开头的请求,将请求交由API Server进行处理(因在同一个Koa2实例,这里直接next()了)。在 public 目录下必须存在 index.html 文件:


<!DOCTYPE html>
<html lang="zh-cn">
<head>
<title>{{ title }}</title>
...
</head>
<body>
<!--vue-ssr-outlet-->
</body>
</html>

开发环境中,处理数据的核心在 config/setup-dev-server.js 文件:


const fs = require('fs')
const path = require('path')
const chalk = require('chalk')
const MFS = require('memory-fs')
const webpack = require('webpack')
const chokidar = require('chokidar')
const apiConfig = require('./webpack.api.config')
const serverConfig = require('./webpack.server.config')
const webConfig = require('./webpack.web.config')