21

服务端预渲染之Nuxt(介绍篇)

 5 years ago
source link: https://segmentfault.com/a/1190000018777955?amp%3Butm_medium=referral
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

现在前端开发一般都是前后端分离, mvvmmvc 的开发框架,如 AngularReactVue 等,虽然写框架能够使我们快速的完成开发,但是由于前后台分离,给项目 SEO 带来很大的不便,搜索引擎在检索的时候是在网页中爬取数据,由于单页面应用读取到的页面是几乎空白的,无法爬取到任何数据信息。

<!DOCTYPE html>
<html>
    <head>
        <meta charset=utf-8>
        <meta name=viewport content="width=device-width,initial-scale=1">
        <title>authorization_web</title>
    </head>
<body>
    <div id=app></div>
</body>
</html>

如上代码,单页面应用查看源代码的时候如上所示,所以搜索引擎无法爬取到任何信息,搜索引擎会认为当前页面为一个空页面。为了解决 SEO 问题,推出了 SSR 服务端预渲染,以便提高对 SEO 优化。

什么是SSR

在认识 SSR 之前,首先对 CSRSSR 之间做个对比。

首先看一下传统的web开发,传统的web开发是,客户端向服务端发送请求,服务端查询数据库,拼接 HTML 字符串(模板),通过一系列的数据处理之后,把整理好的 HTML 返回给客户端,浏览器相当于打开了一个页面。这种比如我们经常听说过的 jsp , PHP , aspx 也就是传统的 MVC 的开发。

SPA 应用,到了 VueReact ,单页面应用优秀的用户体验,逐渐成为了主流,页面整体式 javaScript 渲染出来的,称之为客户端渲染 CSRSPA 渲染过程。由客户端访问 URL 发送请求到服务端,返回 HTML 结构(但是 SPA 的返回的 HTML 结构是非常的小的,只有一个基本的结构,如第一段代码所示)。客户端接收到返回结果之后,在客户端开始渲染 HTML ,渲染时执行对应 javaScript ,最后渲染 template ,渲染完成之后,再次向服务端发送数据请求,注意这里时数据请求,服务端返回 json 格式数据。客户端接收数据,然后完成最终渲染。

SPA 虽然给服务器减轻了压力,但是也是有缺点的:

  1. 首屏渲染时间比较长:必须等待 JavaScript 加载完毕,并且执行完毕,才能渲染出首屏。
  2. SEO 不友好:爬虫只能拿到一个 div 元素,认为页面是空的,不利于 SEO

为了解决如上两个问题,出现了 SSR 解决方案,后端渲染出首屏的 DOM 结构返回,前端拿到内容带上首屏,后续的页面操作,再用单页面路由和渲染,称之为服务端渲染( SSR )。

SSR 渲染流程是这样的,客户端发送 URL 请求到服务端,服务端读取对应的 url 的模板信息,在服务端做出 html数据 的渲染,渲染完成之后返回 html 结构,客户端这时拿到的之后首屏页面的 html 结构。所以用户在浏览首屏的时候速度会很快,因为客户端不需要再次发送 ajax 请求。并不是做了 SSR 我们的页面就不属于 SPA 应用了,它仍然是一个独立的 spa 应用。

SSR 是处于 CSRSPA 应用之间的一个折中的方案,在渲染首屏的时候在服务端做出了渲染,注意仅仅是首屏,其他页面还是需要在客户端渲染的,在 服务端 接收到请求之后并且渲染出首屏页面,会携带着剩余的路由信息预留给 客户端 去渲染其他路由的页面。

Nuxt.js 介绍

Nuxt 官方网站有一句这样的话: Nuxt.js 预设了使您开发 Vue.js 应用程序所需的所有配置。 Nuxt 是一个基于 Vue.js 的通用应用框架。通过对 客户端/服务端 基础框架的抽象组织, Nuxt 主要关注的是应用的 ui 渲染。

通过上面的这些介绍可以简单的得出:

  1. Nuxt 不仅仅用于服务端渲染也可以用于 SPA 应用的开发
  2. 利用 Nuxt 提供的项目结构、异步数据加载,中间件的支持,布局等特性可大幅提升开发效率
  3. Nuxt 可用于网站静态化,可以使用命令将整个网页打包成静态页面,使 SEO 更加友好

Nuxt.js 特性

  1. 基于 Vue
  2. 自动代码分层
  3. 服务端渲染
  4. 强大的路由功能,支持异步数据
  5. 静态文件服务
  6. EcmaScript6EcmaScript7 的语法支持
  7. 打包和压缩 JavaScriptCss
  8. HTML 头部标签管理
  9. 本地开发支持热加载
  10. 集成 ESLint
  11. 支持各种样式预编译器 SASSLESS 等等
  12. 支持 HTTP/2 推送

Nuxt 渲染流程

一个完整的服务器请求到渲染的流程

YrMfMni.png!web

通过上面的流程图可以看出,当一个客户端请求进入的时候,服务端有通过 nuxtServerInit 这个命令执行在 Storeaction 中,在这里接收到客户端请求的时候,可以将一些客户端信息存储到 Store 中,也就是说可以把在服务端存储的一些客户端的一些登录信息存储到 Store 中。之后使用了 中间件 机制,中间件其实就是一个函数,会在每个路由执行之前去执行,在这里可以做很多事情,或者说可以理解为是路由器的拦截器的作用。然后再 validate 执行的时候对客户端携带的参数进行校验,在 asyncDatafetch 进入正式的渲染周期, asyncData 向服务端获取数据,把请求到的数据合并到 Vue 中的 data 中,

Nuxt说明

Nuxt 安装:

确保安装了npx(npx在NPM版本5.2.0默认安装了):

npx create-nuxt-app <项目名>

安装向导:

Project name                                //  项目名称
Project description                         //  项目描述
Use a custom server framework               //  选择服务器框架
Choose features to install                  //  选择安装的特性
Use a custom UI framework                   //  选择UI框架
Use a custom test framework                 //  测试框架
Choose rendering mode                       //  渲染模式
    Universal                                   //  渲染所有连接页面
    Single Page App                             //  只渲染当前页面

这些都是比较重要的其他的配置内容就不做介绍了,一路回车即可。

目录结构介绍

assets              //  存放素材(需要执行webpack预处理操作)
components          //  组件
layouts             //  布局文件
static              //  静态文件(不需要webpack预处理操作)
middleware          //  中间件
pages               //  所有页面
plugins             //  插件
server              //  服务端代码
store               //  vuex

配置文件

const pkg = require('./package')
module.exports = {
  mode: 'universal',    //  当前渲染使用模式
  head: {       //  页面head配置信息
    title: pkg.name,        //  title
    meta: [         //  meat
      { charset: 'utf-8' },
      { name: 'viewport', content: 'width=device-width, initial-scale=1' },
      { hid: 'description', name: 'description', content: pkg.description }
    ],
    link: [     //  favicon,若引用css不会进行打包处理
      { rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' }
    ]
  },
  loading: { color: '#fff' },   //  页面进度条
  css: [    //  全局css(会进行webpack打包处理)
    'element-ui/lib/theme-chalk/index.css'  
  ],
  plugins: [        //  插件
    '@/plugins/element-ui'
  ],
  modules: [        //  模块
    '@nuxtjs/axios',
  ],
  axios: {},
  build: {      //  打包
    transpile: [/^element-ui/],
    extend(config, ctx) {       //  webpack自定义配置
    }
  }
}

Nuxt运行命令

{
  "scripts": {
    //  开发环境
    "dev": "cross-env NODE_ENV=development nodemon server/index.js --watch server",
    //  打包
    "build": "nuxt build",
    //  在服务端运行
    "start": "cross-env NODE_ENV=production node server/index.js",
    //  生成静态页面
    "generate": "nuxt generate"
  }
}

结语

这里简单的对 Nuxt 做了一些介绍,会持续更新对 Nuxt 的跟进,希望会对大家有所帮助,如果有什么问题,可以在下面留言。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK