本文主要讲述如何将一个现有的vue-cli项目按nuxt进行SSR改造。
nuxt官网文档有新项目使用nuxt的相关指南,如有相关需要的可以直接转移到官网了解
nuxt官网地址:nuxt官网
注意官网上相关文档基本都是英文的,如想看中文文档可以在w3cSchool上找到,地址:https://www.w3cschool.cn/nuxtjs/nuxtjs-b4kl36fw.html
1. 背景
今年自己完成了几个项目的开发,基本都是基于自己总结的一整套前后端基础应用来进行开发的,其中前端使用VUE+elementUi(移动端使用vant);开发过程确实爽快;但其中一个项目开发完成后,遇到了大问题:由于采用的是Vue的单页面模式进行开发,网站信息搜索引擎无法做索引!
搜索引擎无法进行索引的核心原因就是,其在爬取网站数据的时候,是不会执行其中包含的JS过程的;而采用Vue的方式开发的应用,其数据都是来源于axios或者其它的ajax方法获取的数据!也就是说,想要友好的支持搜索引擎,就必须采用服务器端渲染的相关技术,比如JSP,就是一个典型的服务器端渲染技术,用户请求一个地址然后展示到浏览器中的数据都是服务器端处理好的,浏览器只管展示;又比如静态页面,所有页面都是预先编写或生成好的,浏览器将请求拿到的数据直接展现即可。
对于Java生态来说,有以下方案可以实现服务器端渲染:
- JSP
- 模板引擎,如Thymeleaf/Velocity等;
- 基于Vue的SSR改造;
JSP基本已经算是步入老年,除了一些非常古老的系统,新的相信已经很少人使用。Thymeleaf在Spring官网文档中都有相关的集成案例,如果是一个全新的项目,应该算是比较好的方案;但对于已经完成前端所有功能开发的项目来说,使用模板引擎重新实现一套成本过高。对于我来说,也只能选择最后一个方案了。
关于Vue服务器端渲染的介绍,可以参考官方文档:https://cn.vuejs.org/v2/guide/ssr.html。这其中主要有两种方式,其一是使用vue-server-renderer插件,其二是使用nuxt;在本项目做改造时,关于vue-server-renderer的介绍不如现有文档清晰,因此使用了nuxt的方案。关于vue-server-renderer的方案,后续有时间再尝试将现有项目进行改造,个人感觉官方的东西按理应该会比nuxt要好用,但由于没用过也无法做出真实的评价,建议有兴趣的可以尝试。
2. 现有项目改造
nuxt与传统的vue-cli项目,在目录结构、路由、组件生命周期上都有所不同;主要的改造步骤如下:
2.1 组件安装
-
nuxt安装 :
cnpm install nuxt --save
-
cross-env:
cnpm install cross-env --save-dev
cross-env主要是在运行npm命令时指定环境变量
-
axios及proxy安装(也可以使用原生的axios)
cnpm install @nuxtjs/axios --save-dev
cnpm install @nuxtjs/proxy --save-dev
2.2 不同环境配置
如果有多个环境,如本地、测试、生产等,那么需要为每个环境指定API接口地址;可以在项目根目录下创建env.js文件,内容如下:
module.exports = {
dev: {
NODE_ENV: 'dev',
URL_PREFIX: '/api/front',
BASE_URL: 'http://localhost:8302',
// BASE_URL: 'http://***',
},
prod: {
NODE_ENV: 'prod',
URL_PREFIX: '/api/front',
BASE_URL: 'http://***',
}
}
这个里面我定义了两个环境,dev与prod;后续在nuxt.config.js中会使用到这些配置的信息;
2.4 修改package.json指令
要启动我们的应用,需要修改package.json文件中的scripts信息,并采用nuxt来执行,scripts定义如下所示:
"scripts": {
"nd": "cross-env NODE_ENV=dev nuxt --mode local",
"nb": "cross-env NODE_ENV=prod nuxt build --mode prod",
"nr": "cross-env NODE_ENV=prod nuxt start --port=3001 --mode prod",
"serve": "cross-env NODE_ENV=prod nuxt --mode prod"
},
上面我定义了几个指定,nd是本地启动的连接dev环境,nb是编译prod环境,nr是启动编译prod后的结果,serve是直接启动prod环境(包含有build与start过程)。
指令定义好后还不能直接启动,需要继续进行改造。
2.3 增加主配置文件nuxt.config.js
如果使用的是vue-cli,其主配置文件是vue.config.js,而nuxt的主配置文件是nuxt.config.js ,我们需要在根目录下创建这个文件,文件内容参考如下:
const env = require('./env');
module.exports = {
env: {
baseUrl: env[process.env.NODE_ENV].BASE_URL,
apiPrefix: env[process.env.NODE_ENV].URL_PREFIX
},
css: [
'@/assets/css/main.scss',
],
plugins: [],
modules: [
'@nuxtjs/axios',
'@nuxtjs/proxy',
'@nuxtjs/style-resources'
],
axios: {
proxy: true,
credentials: true,
},
proxy: {
'/api/front': {
target: env[process.env.NODE_ENV].BASE_URL,
},
'/file': {
target: env[process.env.NODE_ENV].BASE_URL,
},
'/files': {
target: env[process.env.NODE_ENV].BASE_URL,
},
},
head: {
link: [{
rel: 'stylesheet',
href: '//at.alicdn.com/t/font_2040977_ozb90g6ebjp.css'
}, ],
script: [{
// src: 'http://g.tbcdn.cn/mtb/lib-flexible/0.3.4/??flexible_css.js,flexible.js'
}],
meta: [{
charset: 'utf-8'
},
{
name: 'viewport',
content: 'width=device-width,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no'
},
]
},
build: {
extend(config, {
isDev,
isClient
}) {
if (isDev && isClient) {
config.module.rules