npm i koa-router -S
const Router = require('koa-router')
const axios = require('axios')
const path = require('path')
const fs = require('fs')
const MemoryFs = require('memory-fs') //跟node.js中的FS类似。不写入磁盘,输出到memoryFs
const webpack = require('webpack')
const VueServerRender = require('vue-server-renderer') //服务端渲染 复杂工具
const serverRender = require('./server-render')
const serverConfig = require('../../build/webpack.config.server') //webpackconfig
const serverCompiler = webpack(serverConfig) //生成服务端渲染时候的bundle
const mfs = new MemoryFs()
serverCompiler.outputFileSystem = mfs //指定webpack的输出目录
let bundle //记录webpack打包生成的新文件
//webpack相关操作
serverCompiler.watch({}, (err, stats) => { //监听client文件改变,重新打包
if (err) throw err //打包有错,抛出
stats = stats.toJson() //通过stats监听eslint类的错误
stats.errors.forEach(err => console.log(err))
stats.warnings.forEach(warn => console.log(err))
const bundlePath = path.join(
serverConfig.output.path, //webpack配置文件生成的文件
'vue-ssr-server-bundle.json' //注意,不是使用的output中使用的文件名
//插件生成的json文件,默认文件名
)
bundle = JSON.parse(mfs.readFileSync(bundlePath, 'utf-8'))
console.log('new bundle generated')
}) //每次有文件变化,webpack重新打包后,拿到一个新的bundle//处理服务端渲染,要返回的东西
const handleSSR = async (ctx) => {
if (!bundle) { //初次启动,还没有打包好bundle
ctx.body = " wait minutes"
return
}
//通过axios发送一个请求给webpackserver,将
const clientManifestResp = await axios.get(
'http://127.0.0.1:8000/public/vue-ssr-client-manifest.json'
//包含webpack.devserver打包出来的静态文件的路径
//请求路径: 注意要和 dev端一致
//文件名: 由VueClientPlugin(vue-server-render/client-plugin)插件默认自动生成
//在webpack.config.client.js中配置。 类比上面vue-ssr-server-bundle.json
)
const clientManifest = clientManifestResp.data
const template = fs.readFileSync( //step1:拿到模板 path.join(__dirname, '../server.template.ejs'),
'utf-8'
)
const render = VueServerRender //step2:创建一个render
.createBundleRenderer(bundle, {
inject: false, //不用vueServerRender官方提供的template模板
clientManifest //自动生成一个带有script标签的js文件引用的字符串
}) //制造一个bundleRender,再去serverRender
await serverRender(ctx, render, template)
}
const router = new Router()
router.get('*', handleSSR) //所有请求都通过handleSSR来处理
module.exports = router