版本匹配
Vue的SSR渲染,可以当作一个全新的项目,需要安装依赖的模块(node_modules),可以将原先使用vue cli 3创建的项目的package.json拷贝过来,确保不缺少相关模块,然后在此基础上添加SSR需要的模块。
主要是vue-server-renderer:
npm install vue vue-server-renderer --save
vue-server-renderer是SSR渲染的核心,提供bundle renderer来调用renderToString()方法将Vue组件渲染成HTML字符串,需要注意的是vue-server-renderer 和 vue 必须匹配版本,例如@2.6.11版本的vue必须对应@2.6.11版本的vue-server-renderer 。
路由模式history
采用了vue-router的Vue的SSR渲染,必须使用history作为路由模式,因为hash模式的路由提交不到服务器上,如果之前使用的是hash模式,需要进行修改:
const router = new Router({
mode: 'history',
...
})
两个入口
Vue的SSR渲染,一般都会是同构的,也就是业务代码是一套,通过不同的构建配置,来分别构建客户端client和服务端server,对webpack构建而言,这就需要有两个入口,修改vue.config.js来支持,代码如下:
const TARGET_NODE = process.env.WEBPACK_TARGET === 'node'
const target = TARGET_NODE ? 'server' : 'client'
...
configureWebpack: {
// 将 entry 指向应用程序的 server / client 文件
entry: `./src/entry-${target}.js`,
// 这允许 webpack 以 Node 适用方式(Node-appropriate fashion)处理动态导入(dynamic import),
// 并且还会在编译 Vue 组件时,
// 告知 `vue-loader` 输送面向服务器代码(server-oriented code)。
target: TARGET_NODE ? 'node' : 'web',
// node: TARGET_NODE? undefined : false,
// 此处告知 server bundle 使用 Node 风格导出模块(Node-style exports)
output: {
libraryTarget: TARGET_NODE ? 'commonjs2' : undefined
},
// devtool: 'source-map',
// https://webpack.js.org/configuration/externals/#function
// https://github.com/liady/webpack-node-externals
// 外置化应用程序依赖模块。可以使服务器构建速度更快,
// 并生成较小的 bundle 文件。
externals: TARGET_NODE ? nodeExternals({
// 不要外置化 webpack 需要处理的依赖模块。
// 你可以在这里添加更多的文件类型。例如,未处理 *.vue 原始文件,
// 你还应该将修改 `global`(例如 polyfill)的依赖模块列入白名单
whitelist: /\.css$/
}) : undefined,
optimization: {
splitChunks: false
},
},
chainWebpack: config => {
config.module
.rule('vue')
.use('vue-loader')
.ta