改造Vue-cli支持ssr,从入门到放弃(连载一)
项目背景
项目需要在一周的时间内解决个性化分享的问题,时间比较紧急。
项目是前期使用Vue-cli
创建的,已经过几个月的开发迭代,有了10几个页面,需要解决分享时自定义标题/描述/图片等信息的问题,而Vue-cli只能创建单页面应用,内容页无法根据文章的内容动态设置Meta信息。
当时主要有两个方案。
方案一、在Vue-cli的基础上改造,使之支持SSR
之所以考虑这种方案,有两个原因,1、之前有在React上使用ssr项目的经验,可以借鉴;2、该项目是个用户端产品,需要保持轻量级和灵活度,如果较多使用第三方框架,恐怕会受制于人,造成后续维护成本偏高,如移除前期使用的element-ui
就花了很多精力。
这种方案的特点是,业务逻辑代码基本不需要动,ssr部分需要从零开始。
方案二、将项目业务代码迁移到NuxtJS
之前用过NuxtJS,相对熟悉。而且NuxtJS经过多年发展,已经非常成熟。这种方案的特点是,ssr部分基本上不需要担心,但是业务代码迁移的过程会碰到什么问题,没有概念。
既然两个方案都有不确定性,先拿第一种尝试(业务上的灵活性+技术上的挑战性)。
实施方案一
这个方案最终失败,所以只是简单介绍一下自定义ssr的一些关键点。
-
ssr需要项目同时满足在客户端和服务端运行。而Vue-cli只有一个客户端的入口
main.js
。我们需要将其入口文件拆分为client-entry.js
和server-entry.js
。其中client-entry.js
相当于main.js
,而server-entry.js
是给nodejs使用的。 -
对于所有业务代码,需要兼容node环境。对于很难复用的代码,可以写两份,一份只在浏览器运行,一份只在node运行;更多的场景,可以通过判断执行环境是否是浏览器而做不同的处理。示例如下:
function isBrowser() {
return typeof window !== 'undefined'
}
- 项目中用到的vue组件,如果不是必须要在服务端泻染,则有更简单的方案。也就是将组件放到vue项目自带的
client-only
组件之中。示例如下:
<client-only>
<my-swiper />
</client-only>
为何放弃
-
构建工具。改选spa到ssr,不仅仅涉及到业务代码,有一个很大的挑战,是要非常熟悉构建工具,特别是vue-cli相关的构建。比如说要创建一个
npm run serve:ssr
的开发环境,需要熟悉如何做vue-cli插件。 -
ssr要考虑的因素多得超过预期。比如Meta的设置,还是用第三方成熟的
vue-meta
比较香,只是整合起来也并非能一帆风顺。
实施方案二
之所以在方案一耽误了一些时间的情况下,还考虑方案二,得益于之前的使用经验,又请教了大厂NuxtJS实际使用者的帮助。NuxtJS
虽然文档写得很全,但是对于一个刚刚接触的人来说,想短时间理解实战中的关键点,最好的方式,是有人帮忙。比如说,官网上有个章节介绍了plugins
的用法,但我并不能很快地理解它是用来解决业务代码兼容服务端/客户端的推荐方式。
最终的迁移过程,还是比较顺利的。除了国际化代码的部分,踩了一点坑。具体迁移步骤如下:
- vue-cli/src/views -> nuxtjs/pages
- vue-cli/src/store -> nuxtjs/store
- vue-cli/src/components -> nuxtjs/components
- vue-cli/src/assets -> nuxtjs/assets
- vue-cli/public -> nuxtjs/static
- 将需要全局引用的js代码,比如utils.js,迁移到
nuxtjs/plugins
,将其只能运行在服务端的部分,拆分成另一个文件,比如utils-server.js
。并在nuxt.config.js的plugins配置部分分别引入。 - vue-cli/router目录,在nuxtjs中是不需要的。nuxtjs会自动将pages目录中的文件生成路由。