Vue 项目 SSR 改造实战

我们先看“疗效”,你可以打开我的博客u3xyz.com,通过查看源代码来看SSR直出效果。我的博客已经快上线一年了,但不吹不黑,访问量非常地小,我也一直在想办法提升访问量(包括在sf写文章,哈哈)。当然,在PC端,搜索引擎一直都是一个重要的流量来源。这里就不得不提到SEO。下图是我的博客以前在百度的快照:

1460000012440046

细心的朋友会发现,这个快照非常简单,简单到几乎什么都没有。这也是没办法的事,博客是基于Vue的SPA页面,整个项目本来就是一个“空架子”,这个快照从博客2月份上线以来就一直是上面的样子,直到最近上线SSR。搜索引擎蜘蛛每次来抓取你的网站都是一个样子,慢慢得,它也就不会来了,相应的,网站的权重,排名肯定不会好。到目前为此,我的博客不用网址进行搜索都搜不到。在上线了SSR后,再加上一些SEO优化,百度快照终于更新了:

1460000012440047

为什么要做SSR

文章开始基本已经回答了为什么要做SSR这个问题,当然,还有另一个原因是SSR概念现在在前端非常火,无奈在实际项目中没有机会,也只有拿博客来练手了。下面将详细介绍本博客项目SSR全过程。

SSR改造实战

总的来说SSR改造还是相当容易的。推荐在动手之前,先了解官方文档官方Vue SSR Demo,这会让我们事半功倍。

1. 构建改造

1460000012440048

上图是Vue官方的SSR原理介绍图片。从这张图片,我们可以知道:我们需要通过Webpack打包生成两份bundle文件:

  • Client Bundle,给浏览器用。和纯Vue前端项目Bundle类似
  • Server Bundle,供服务端SSR使用,一个json文件

不管你项目先前是什么样子,是否是使用vue-cli生成的。都会有这个构建改造过程。在构建改造这里会用到 vue-server-renderer 库,这里要注意的是 vue-server-renderer 版本要与Vue版本一样。下图是我的构建文件目录:

1460000012440049

  • util.js 提供一些公共方法
  • webpack.base.js是公共的配置
  • webpack.client.js 是生成Client Bundle的配置。核心配置如下:

  • webpack.server.js 是生成Server Bundle的配置,核心配置如下:

2. 代码改造

2.1 必须使用VueRouter, Vuex。ajax库建议使用axios

可能你的项目没有使用VueRouter或Vuex。但遗憾的是,Vue-SSR必须基于 Vue + VueRouter + Vuex。Vuex官方没有提,但其实文档和Demo都是基于Vuex。我的博客以前也没有用Vuex,但经过一翻折腾后,还是乖乖加上了Vuex。另外,因为代码要能同时在浏览器和Node.js环境中运行,所以ajax库建议使用axios这样的跨平台库。

2.2 两个打包入口(entry),重构app, store, router, 为每个对象增加工厂方法createXXX

每个用户通过浏览器访问Vue页面时,都是一个全新的上下文,但在服务端,应用启动后就一直运行着,处理每个用户请求的都是在同一个应用上下文中。为了不串数据,需要为每次SSR请求,创建全新的app, store, router

1460000012440050

上图是我的项目文件目录。

  • app.js, 通用的启动Vue应用代码
  • App.vue,Vue应用根组件
  • entry.client.js,浏览器环境入口
  • entry.server.js,服务器环境入口
  • index.html,html模板

再看一下具体实现的核心代码:

3. 重构组件获取数据方式

关于状态管理,要严格遵守Redux思想。建议把应用所有状态都存于store中,组件使用时再mapState下来,状态更改严格使用action的方式。另一个要提一点的是,action要返回promise。这样我们就可以使用asyncData方法获取组件数据了

3. SSR服务器实现

在完成构建和代码改造后,如果一切顺利。我们能得到下面的打包文件:

1460000012440051

这时,我们可以开始实现SSR服务端代码了。下面是我博客SSR实现(基于Koa)

4. 服务器部署

服务器部署,跟你的项目架构有关。比如我的博客项目在服务端有2个后端服务,一个数据库服务,nginx用于请求转发:

1460000012440052

5. 遇到的问题及解决办法

加载不到组件的JS文件

解决办法:

去掉webpack配置中的output.chunkFilename: getFileName(‘js/main[name]-$hash.js’)

所以对webpack.server.js不要对配置CommonsChunkPlugin,也不要设置output.chunkFilename

代码高亮codeMirror使用到navigator对象,只能在浏览器环境运行

把执行逻辑放到mounted回调中。实现不行,就封装一个异步组件,把组件的初始化放到mounted中:

串数据

dispatch的action没有返回promise,保证返回promise即可

路由跳转

路由跳转使用router方法或标签,这两种方式能自适应浏览器端和服务端,不要使用a标签

小结

本文主要记录了我的博客u3xyz.comSSR过程:

  • 构建webpack改造
  • 代码改造
  • server端SSR实现
  • 上线部署

最后希望文章能对大家有些许帮助!

1 4 收藏 评论

相关文章

可能感兴趣的话题



直接登录
跳到底部
返回顶部