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
| const webpack = require('webpack') const axios = require('axios') const MemoryFS = require('memory-fs') const fs = require('fs') const path = require('path') const send = require('koa-send') const Router = require('koa-router')
const webpackConfig = require('@vue/cli-service/webpack.config') const { createBundleRenderer } = require('vue-server-renderer')
const serverCompiler = webpack(webpackConfig) const mfs = new MemoryFS()
serverCompiler.outputFileSystem = mfs
let bundle serverCompiler.watch({}, (err, stats) =>{ if (err) { throw err } stats = stats.toJson() stats.errors.forEach(error => console.error(error) ) stats.warnings.forEach( warn => console.warn(warn) ) const bundlePath = path.join( webpackConfig.output.path, 'vue-ssr-server-bundle.json' ) bundle = JSON.parse(mfs.readFileSync(bundlePath,'utf-8')) console.log('new bundle generated') })
const handleRequest = async ctx => { if (! bundle) { ctx.body = '等待webpack打包完成后在访问在访问' return }
const url = ctx.path if (url.includes('favicon.ico')){ console.log(`proxy ${url}`) return await send(ctx, url, { root: path.resolve(__dirname, '../public') }) }
const clientManifestResp = await axios.get('http://localhost:8080/vue-ssr-client-manifest.json') const clientManifest = clientManifestResp.data
const renderer = createBundleRenderer(bundle, { runInNewContext: false, template: fs.readFileSync(path.resolve(__dirname, '../public/index.template.html'), 'utf-8'), clientManifest: clientManifest })
const context = { title: 'Rua', url }
const html = await renderToString(context, renderer) ctx.body = html }
const renderToString = (context, renderer) => { return new Promise((resolve, reject) => { renderer.renderToString(context, (err, html) => { err ? reject(err) : resolve(html) }) }) }
const router = new Router()
router.get('*', handleRequest)
module.exports = router
|