时间:2021-05-26
服务端渲染(SSR)
将一个 Vue 组件在服务端渲染成 HTML 字符串并发送到浏览器,最后将这些静态标记“激活”为可交互应用程序的过程就叫服务端渲染(SSR)
服务器渲染的 Vue.js 应用程序也可以被认为是"同构"或"通用",因为应用程序的大部分代码都可以在服务器和客户端上运行
为什么使用 服务端渲染(SSR)
服务端渲染(SSR)缺点
服务端渲染(SSR)vs 预渲染(Prerendering)
如果你只是想改善少数营销页面(例如 /, /about, /contact 等)的 SEO,那么你可能需要预渲染,无需使用 web 服务器实时动态编译 HTML,而是使用预渲染方式,在构建时简单地生成针对特定路由的静态 HTML 文件,优点是设置预渲染更简单,并可以将你的前端作为一个完全静态的站点
如果你使用 webpack,你可以使用 prerender-spa-plugin (npm地址) 插件轻松地添加预渲染
服务端渲染(SSR)原理
构建流程:所有的文件拥有一个公共入口 app.js,进入服务端入口 entry-server.js 和客户端入口 entry-client.js ,项目完成后通过使用 webpack 打包生成服务端 server bundle(一个供服务端 SSR 使用的 json 文件)和客户端 client bundle(用于浏览器),当请求页面时,服务端将 vue 组件组装成 HTML 字符串发送到浏览器,混入到客户端访问的 HTML 模板中,完成页面渲染
通过 vuecli 创建 vue 项目
vue create vue-ssr-demovue-server-renderer
vue-server-renderer 是 SSR 渲染的核心,提供 createRenderer 方法,这个方法的 renderToString 可以把 app 渲染成字符串。createBundleRenderer 方法可以通过预打包应用程序代码创建 bundleRenderer 实例,来渲染 bundle 和 HTML 模板
安装 vue-server-renderer
npm install vue-server-renderer --save注意:
避免状态单例
Node.js 服务器是一个长期运行的进程,当我们的代码进入该进程时,它将进行一次取值并留存在内存中,这意味着如果创建一个单例对象,它将在每个传入的请求之间共享,所以我们应该暴露一个可以重复执行的工厂函数,为每个请求创建一个新的根 Vue 实例,如果我们在多个请求之间使用一个共享的实例,很容易导致交叉请求状态污染(同样的规则也适用于 router、store 和 event bus 实例)
创建 路由 router
安装 vue-router
npm install vue-router --save在 src 目录下创建 router 文件夹和 index.js
在 components 目录下创建 Home.vue 和 About.vue 页面(根据项目需求自定义创建)
router/index.js:
import Vue from "vue"import Router from "vue-router"import Home from "@/components/Home"import About from "@/components/About"Vue.use(Router)//每次用户请求都需要创建一个新的router实例//创建createRouter工厂函数export default function createRouter() { //创建router实例 return new Router({ mode: "history", routes: [ { path: "/", name: 'home', component: Home }, { path: "/about", name: 'about', component: About } ] })}修改 App.vue
修改 App.vue 页面,进行页面布局(根据项目需求自定义布局)
App.vue:
<template> <div id="app"> <nav> <router-link to="/">首页</router-link> <router-link to="/about">关于</router-link> </nav> <router-view></router-view> </div></template>创建 公共入口 app.js
在 src 目录下创建 公共入口 app.js ,用于创建 vue 实例
app.js:
import Vue from "vue"import App from "./App.vue"import createRouter from "./router"//创建createApp工厂函数export default function createApp() { const router = createRouter() //创建vue实例 const app = new Vue({ router, render: h => h(App), }) return { app, router }}创建 服务端入口 entry-server.js
在 src 目录下创建 服务端入口 entry-server.js ,用于渲染首屏
entry-server.js:
import createApp from "./app"export default context => { return new Promise((resolve, reject) => { const { app, router } = createApp() //渲染首屏 router.push(context.url) router.onReady(() => { resolve(app) }, reject) })}创建 客户端入口 entry-client.js
在 src 目录下创建 客户端入口 entry-client.js ,用于挂载激活 app
entry-client.js:
import createApp from "./app"const { app, router } = createApp()router.onReady(() => { //挂载激活app app.$mount("#app")})创建 页面模板 index.temp.html
在 public 目录下创建 index.temp.html ,作为渲染 Vue 应用程序时,renderer 生成 HTML 页面包裹容器,来包裹生成的 HTML 标记
<!--vue-ssr-outlet--> 注释将是应用程序 HTML 标记注入的地方
index.temp.html:
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>vue ssr</title></head><body> <!--vue-ssr-outlet--></body></html>创建 Node.js 服务器
服务端渲染(SSR)需要使用 Node.js 服务器,这里使用 express 框架搭建
安装 express
根目录下创建 server.js 文件,用于搭建 Node.js 服务器
server.js:
//nodejs服务器const express = require("express")const Vue = require("vue")const fs = require("fs")//创建express实例const app = express()//创建渲染器const { createBundleRenderer } = require("vue-server-renderer")const serverBundle = require("./dist/server/vue-ssr-server-bundle.json")const clientManifest = require("./dist/client/vue-ssr-client-manifest.json")const renderer = createBundleRenderer(serverBundle, { runInNewContext: false, template: fs.readFileSync("./public/index.temp.html", "utf-8"), //页面模板 clientManifest})//中间件处理静态文件请求app.use(express.static("./dist/client", {index: false}))//将路由的处理交给vueapp.get("*", async (req, res) => { try { const context = { url: req.url, title: "" } const html = await renderer.renderToString(context) res.send(html) }catch { res.status(500).send("服务器内部错误!") }})app.listen(9999, () => { console.log("服务器渲染成功!")})webpack 打包配置
根目录下创建 vue 配置文件 vue.config.js 进行 webpack 配置,该配置会覆盖 vue-cli 中 webpack 的默认配置
vue.config.js:
const VueSSRServerPlugin = require("vue-server-renderer/server-plugin")const VueSSRClientPlugin = require("vue-server-renderer/client-plugin")//环境变量,决定入口是客户端还是服务端const TARGRT_NODE = process.env.WEBPACK_TARGET === "node"const target = TARGRT_NODE ? "server" : "client"module.exports = { css: { extract: false }, outputDir: "./dist/" + target, configureWebpack: () => ({ //将 entry 指向应用程序的 server entry 文件 entry: `./src/entry-${target}.js`, //对 bundle renderer 提供 source map 支持 devtool: "source-map", //这允许 webpack 以 Node 适用方式(Node-appropriate fashion)处理动态导入(dynamic import) //并且还会在编译 Vue 组件时,告知 `vue-loader` 输送面向服务器代码(server-oriented code) target: TARGRT_NODE ? "node" : "web", node: TARGRT_NODE ? undefined : false, output: { //此处告知 server bundle 使用 Node 风格导出模块(Node-style exports) libraryTarget: TARGRT_NODE ? "commonjs2" : undefined }, optimization: { splitChunks: TARGRT_NODE ? false : undefined }, //将服务器的整个输出构建为单个 JOSN 文件的插件 //服务端默认文件名为 vue-ssr-server-bundle.json plugins: [TARGRT_NODE ? new VueSSRServerPlugin() : new VueSSRClientPlugin()] })}打包脚本配置
cross-env 插件:运行跨平台设置和使用环境变量的脚本
安装 cross-env 插件
在 package.json 文件中定义项目运行打包脚本
package.json:
{ ...... "scripts": { "server": "node server", "build:client": "vue-cli-service build", "build:server": "cross-env WEBPACK_TARGET=node vue-cli-service build --mode server", "build": "npm run build:server && npm run build:client" }, ......}终端执行命令打包项目:
npm run build打包完成后,终端执行命令启动 Node.js 服务器
npm run server服务器启动后,浏览器打开 localhost:9999 即可访问 SSR 项目
查看网页源代码发现根元素上添加了一个特殊的属性:data-server-rendered,该属性让客户端 Vue 知道这部分 HTML 是由 Vue 在服务端渲染的,并且应该以激活模式进行挂载
项目目录:
打包后 dist 目录:
到此这篇关于vuecli项目构建SSR服务端渲染的实现的文章就介绍到这了,更多相关vuecli构建SSR服务端渲染内容请搜索以前的文章或继续浏览下面的相关文章希望大家以后多多支持!
声明:本页内容来源网络,仅供用户参考;我单位不保证亦不表示资料全面及准确无误,也不保证亦不表示这些资料为最新信息,如因任何原因,本网内容或者用户因倚赖本网内容造成任何损失或损害,我单位将不会负任何法律责任。如涉及版权问题,请提交至online#300.cn邮箱联系删除。
对于React,Vue构建的单页面应用老说,SEO是一个众所周知的问题。服务端渲染(SSR-serverSideRender)是目前看来最好的解决办法。Reac
我们已经熟悉React服务端渲染(SSR)的基本步骤,现在让我们更进一步利用ReactRouterV4实现客户端和服务端的同构。毕竟大多数的应用都需要用到web
>初学ssr入坑初学vue服务端渲染疑惑非常多,我们大部分前端都是半路出家,上手都是前后端分离,对服务端并不了解,不说java、php语言了,连node服务都还
首先,这个例子用到了服务端渲染的技术。服务端渲染,说白了就是在服务端使用模板引擎,这里我先简单的介绍一下服务端渲染与客户端渲染之间的区别。服务端渲染与客户端渲染
Nuxt.js是一个基于Vue.js的通用应用框架。通过对客户端/服务端基础架构的抽象组织,Nuxt.js主要关注的是应用的UI渲染。SSR,即服务器渲染,就是