SSR
(同构应用)的意义
SEO
- 首屏直出,减少白屏
- 更多的前端自由度和控制力
前端SSR
的优势
- 利用现代框架
vue
react
等 可以在很大程度上做到代码业务逻辑的复用 - 使用
node
对于前端同学来说有天然的语言优势,利用javascript
同时完成服务端和客户端的开发。
如何进行SSR
- 将vue组件渲染成html文本
vue
是依赖官方提供的vue-server-renderer
包,将我们的vue
实例转换成字符串(html 标记)。
// 基础使用
const app = new Vue({...});
const renderer = require('vue-server-renderer').createRenderer()
renderer.renderToString(app, (err, html) => {
// 输出html
})
使用模板
- 准备一个html模板
<!DOCTYPE html>
<html lang="en">
<head><title>Hello</title></head>
<body>
<!--vue-ssr-outlet-->
</body>
</html>
- 使用
template
选项
const renderer = createRenderer({
template: require('fs').readFileSync('./index.template.html', 'utf-8')
})
renderer.renderToString(app, (err, html) => {
console.log(html) // html 将是注入应用程序内容的完整页面
})
-
针对客户端和服务端提供不同的入口文件,以供
webpack
进行编译构建。
尤其是服务端代码需要注意避免单例,造成状态混乱;做法就是到处一个函数,每个请求过来,都创建一个全新的实例对象 进行相应处理。 -
路由如何做到同构?
依赖vue-router
的支持,我们可以对同一个请求url,在服务端渲染和客户端渲染同时能够做出响应。
① 针对客户端来说,vue-router
自动帮我们执行所有的后续逻辑:获取当前的url
,在我们的路由配置中获取对应的组件,执行生命周期,执行渲染。
② 对于服务端来说,我们需要获取当前的url
,router.push(url)
, 从而驱动后面的流程执行。 -
接口请求逻辑如何同构?
① 如何将数据预期进行共享。
(1)组件上定义asyncData
方法
(2)服务端直接在匹配路由的时候进行预取
(3)客户端可以选择在beforeResolve
afterEach
beforeMount
等时机进行接口请求, 另外需要在beforeRouteUpdate
中进行更新。
② 如何将服务端预期的数据和客户端共享,在客户端渲染能够混合成功。
(1)服务端渲染的时候,通过将预取的数据添加到context.state
上,最终会将context.state
赋值给window. __INITIAL_STATE__
上,然后router
可以调用store.replaceState
来重新初始化store
的数据
(2)客户端渲染的时候 发现 data-server-rendered
属性,会采用激活模式,不会重新生成一遍DOM.
- 客户端和服务端的
webpack
配置。
因为使用createBundleRenderer
的时候
const {createBundleRenderer} = require('vue-server-renderer');
const template = require('fs').readFileSync('/path/to/template.html', 'utf-8')
const serverBundle = require('/path/to/vue-ssr-server-bundle.json')
const clientManifest = require('/path/to/vue-ssr-client-manifest.json')
const renderer = createBundleRenderer(serverBundle, {
template,
clientManifest
})
客户端配置 需要生成clientManifest
,依赖了vue-server-renderer/client-plugin
服务端配置 需要生成serverBundle
, 依赖了vue-server-renderer/server-plugin
并且需要导出符合node 模块得包
target: 'node',
output: {
libraryTarget: 'commonjs2'
},
plugins: [
new VueSSRServerPlugin()
]
SSR的注意事项
- 避免单例
- 客户端和服务端环境的兼容
网友评论