2023年6月29日发(作者:)
通过vue-cli3构建⼀个SSR应⽤程序的⽅法1、前沿1.1、什么是SSRSSR(服务端渲染)顾名思义就是将页⾯在服务端渲染完成后在客户端直接展⽰。1.2、客户端渲染与服务端渲染的区别 传统的SPA模式即客户端渲染的模式1. 构建的应⽤程序,默认情况下是有⼀个html模板页,然后通过webpack打包⽣成⼀堆js、css等等资源⽂件。然后塞到中2. ⽤户输⼊url访问页⾯ -> 先得到⼀个html模板页 -> 然后通过异步请求服务端数据 -> 得到服务端的数据 -> 渲染成局部页⾯ ->⽤户SSR模式即服务端渲染模式⽤户输⼊url访问页⾯ -> 服务端接收到请求 -> 将对应请求的数据渲染完⼀个⽹页 -> 返回给⽤户 1.3、为什么要使⽤SSR呢?ssr的好处官⽹已经给出,最有意思的两个优点如下:1. 更有好的SEO。由于搜索引擎爬⾍抓取⼯具可以直接查看完全渲染的页⾯。2. 更快的内容到达时间(time-to-content)1.4、SSR原理这是官⽅的SSR原理介绍图,从这张图⽚,我们可以知道:我们需要通过Webpack打包⽣成两份bundle⽂件:Client Bundle,给浏览器⽤。和纯Vue前端项⽬Bundle类似Server Bundle,供服务端SSR使⽤,⼀个json⽂件不管你项⽬先前是什么样⼦,是否是使⽤vue-cli⽣成的。都会有这个构建改造过程。在构建改造这⾥会⽤到 vue-server-renderer库,这⾥要注意的是 vue-server-renderer 版本要与Vue版本⼀样。
2、开始构建基于vue-cli3 的SSR应⽤程序了解ssr原理后,来开始step by step搭建⼀个⾃⼰的SSR应⽤程序安装vue-cli3全局安装vue-cli脚⼿架npm install @vue/cli -g --registry=创建⼀个vue项⽬vue create ssr-example
会进⼊到⼀个交互bash界⾯,按⾃⼰需要选择⼀步⼀步回车,根据⾃⼰需要选择运⾏项⽬npm run serve看到这个提⽰,说明成功了⼀半了,接下来进⾏后⼀半的改造。3、进⾏SSR改造3.1 安装需要的包1. 安装 vue-server-renderer2. 安装 3. 安装 webpack-node-externals4. 安装 cross-envnpm install vue-server-renderer webpack-node-externals cross-env --registry= --save-dev3.2 在服务器中集成在项⽬根⽬录下新建⼀个安装koa2npm install koa koa-static --save --registry=在koa2集成ssr// // 第 1 步:创建⼀个 Vue 实例const Vue = require("vue");const Koa = require("koa");const app = new Koa();// 第 2 步:创建⼀个 rendererconst renderer = require("vue-server-renderer").createRenderer();// 第 3 步:添加⼀个中间件来处理所有请求(async (ctx, next) => { const vm = new Vue({ data: { title: "ssr example", url: }, template: `
访问的 URL 是: {{ url }}
` }); // 将 Vue 实例渲染为 HTML ToString(vm, (err, html) => { if(err){ (500).end('Internal Server Error') return } = html });});const port = 3000;(port, function() { (`server started at localhost:${port}`);});运⾏ 看到这个说明⼀个简单的ssr构建成功了。不过到⽬前为⽌,我们并没有将客户端的.vue⽂件通过服务端进⾏渲染,那么如何将前端的.vue⽂件与后端node进⾏结合呢?3.3 改造前端配置,以⽀持SSR1、修改源码结构在src⽬录下新建两个⽂件,⼀个 仅运⾏于浏览器 ⼀个 仅运⾏于服务器修改 是我们应⽤程序的「通⽤ entry」。在纯客户端应⽤程序中,我们将在此⽂件中创建根 Vue 实例,并直接挂载到 DOM。但是,对于服务器端渲染(SSR),责任转移到纯客户端 entry ⽂件。 简单地使⽤ export 导出⼀个 createApp 函数:// rt Vue from 'vue'import App from './'import { createRouter } from "./router";// 导出⼀个⼯⼚函数,⽤于创建新的// 应⽤程序、router 和 store 实例export function createApp () { const router = createRouter(); const app = new Vue({ router, // 根实例简单的渲染应⽤程序组件。 render: h => h(App) }) return { app }}修改客户端 entry 只需创建应⽤程序,并且将其挂载到 DOM 中import { createApp } from './app'// 客户端特定引导逻辑……const { app } = createApp()// 这⾥假定 模板中根元素具有 `id="app"`app.$mount('#app')修改服务器 entry 使⽤ default export 导出函数,并在每次渲染中重复调⽤此函数。import { createApp } from "./main";export default context => { // 因为有可能会是异步路由钩⼦函数或组件,所以我们将返回⼀个 Promise, // 以便服务器能够等待所有的内容在渲染前, // 就已经准备就绪。 return new Promise((resolve, reject) => { const { app, router, store } = createApp(); // 设置服务器端 router 的位置 (); // 等到 router 将可能的异步组件和钩⼦函数解析完 y(() => { const matchedComponents = chedComponents(); // 匹配不到的路由,执⾏ reject 函数,并返回 404 if (!) { return reject({ code: 404 }); } // Promise 应该 resolve 应⽤程序实例,以便它可以渲染 resolve(app); }, reject); });};修改rt Vue from 'vue'import Router from 'vue-router'import Home from './views/'(Router)export function createRouter(){ return new Router({ mode: 'history', //⼀定要是history模式 routes: [ { path: '/', name: 'home', component: Home }, { path: '/about', name: 'about', component: () => import(/* webpackChunkName: "about" */ './views/') } ] })}2、修改webpack配置在vue-cli3创建的vue项⽬,已经没有了之前的、、。那么如何进⾏webpack的配置呢?在官⽹上也说明了如何使⽤。 调整 webpack 配置最简单的⽅式就是在 中的 configureWebpack 选项提供⼀个对象,该对象将会被 合并⼊最终的 webpack 配置。在项⽬根⽬录下,新建⼀个// t VueSSRServerPlugin = require("vue-server-renderer/server-plugin");const VueSSRClientPlugin = require("vue-server-renderer/client-plugin");const nodeExternals = require("webpack-node-externals");const merge = require("");const TARGET_NODE = K_TARGET === "node";const target = TARGET_NODE ? "server" : "client";s = { configureWebpack: () => ({ // 将 entry 指向应⽤程序的 server / client ⽂件 entry: `./src/entry-${target}.js`, // 对 bundle renderer 提供 source map ⽀持 devtool: 'source-map', target: TARGET_NODE ? "node" : "web", node: TARGET_NODE ? undefined : false, output: { libraryTarget: TARGET_NODE ? "commonjs2" : undefined }, // /configuration/externals/#function // /liady/webpack-node-externals // 外置化应⽤程序依赖模块。可以使服务器构建速度更快, // 并⽣成较⼩的 bundle ⽂件。 externals: nodeExternals({ // 不要外置化 webpack 需要处理的依赖模块。 // 你可以在这⾥添加更多的⽂件类型。例如,未处理 *.vue 原始⽂件, // 你还应该将修改 `global`(例如 polyfill)的依赖模块列⼊⽩名单 whitelist: [/.css$/] }), optimization: { splitChunks: { chunks: "async", minSize: 30000, minChunks: 2, maxAsyncRequests: 5, maxInitialRequests: 3 } }, plugins: [TARGET_NODE ? new VueSSRServerPlugin() : new VueSSRClientPlugin()] }), chainWebpack: config => { .rule("vue") .use("vue-loader") .tap(options => { merge(options, { optimizeSSR: false }); }); }};修改package,新增三个脚本来⽣成"build:client": "vue-cli-service build","build:server": "cross-env WEBPACK_TARGET=node vue-cli-service build","build:win": "npm run build:server && move bundle && npm run build:client && move bundle ",
执⾏命令npm run build:win在dist⽬录下会⽣成两个json⽂件
3.4 改造 代码const fs = require("fs");const Koa = require("koa");const path = require("path");const koaStatic = require('koa-static')const app = new Koa();const resolve = file => e(__dirname, file);// 开放dist⽬录(koaStatic(resolve('./dist')))// 第 2 步:获得⼀个createBundleRendererconst { createBundleRenderer } = require("vue-server-renderer");const bundle = require("./dist/");const clientManifest = require("./dist/");const renderer = createBundleRenderer(bundle, { runInNewContext: false, template: leSync(resolve("./src/"), "utf-8"), clientManifest: clientManifest});function renderToString(context) { return new Promise((resolve, reject) => { ToString(context, (err, html) => { err ? reject(err) : resolve(html); }); });}// 第 3 步:添加⼀个中间件来处理所有请求(async (ctx, next) => { const context = { title: "ssr test", url: }; // 将 context 数据渲染为 HTML const html = await renderToString(context); = html;});const port = 3000;(port, function() { (`server started at localhost:${port}`);});3.5 运⾏ 访问localhost:3000,可以看到页⾯的数据都是⼜服务端渲染完成后返回的。到这⼀步已经基本算完成了SSR的构建了。如果有问题的话,可以把dist⽬录下的⽂件删了。避免直接访问到了该html⽂件。
4、集成vuex修改rt Vue from 'vue'import Vuex from 'vuex'(Vuex)export function createStore() { return new ({ state: { }, mutations: { }, actions: { } });}修改rt Vue from "vue";import App from "./";import { createRouter } from "@/router";import { createStore } from "@/store";export function createApp() { const router = createRouter(); const store = createStore() // + const app = new Vue({ router, store, // + render: h => h(App) }); return { app, router };}再次运⾏脚本构建npm run build:winnode 5、案例代码6、总结到⽬前为⽌,仅仅是完成了SSR的基础部分,还有相关的 SSR热更新之类的问题还需要继续探索。如果有好的热更新⽅法欢迎发出了参考参考。以上就是本⽂的全部内容,希望对⼤家的学习有所帮助,也希望⼤家多多⽀持。
发布者:admin,转转请注明出处:http://www.yc00.com/xiaochengxu/1687986192a64000.html
评论列表(0条)