手写SSR服务器

#参考文章:

https://blog.csdn.net/lireign/article/details/121912888

#参考视频:

https://www.bilibili.com/video/BV1wY4y1w7S6/?p=4&spm_id_from=333.880.my_history.page.click&vd_source=eeb7ae40bd78a24b0434b669a8496d07

一,相关概念

SPAsingle page web application,单页 Web 应用。Web 不再是一张张页面,而是一个整体的应用,一个由路由系统、数据系统、页面(组件)系统等等,组成的应用程序。

SEOSearch Engine Optimization,搜索引擎优化。通过各种技术(手段)来确保,我们的Web内容被搜索引擎最大化收录,最大化提高权重,最终带来更多流量。但爬虫收录的数据存在优先级(HTML > JSP > VUE),为了使更有利于爬虫和搜索,将页面和数据进行整合。

SSRServer Side Render,服务端渲染。SSR在服务端进行渲染生成html文件,浏览器显示html文件。SPA程序不利于SEO,SSR就是前端对于SEO的解决方案。

二,实现思路

在index.html中插入一个占位符,将真实数据替换掉占位符

三,简单模拟

①创建一个index.html

②初始化包管理工具

1
npm init -y

③安装express

1
npm i express

④创建app.js

并测试我们创建的服务器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
const express = require('express')

function SSRServer(){
const app = express();

app.use("*",(req, res) => {
console.log("执行了app.use");
})

app.listen(3001,()=>{
console.log("listening on http://localhost:3001");
})
}
SSRServer()

image-20230304153913884

证明我们的服务器可以运行

⑥填充替换的逻辑

首先在index.html中插入占位符

1
2
3
<div id="app">
<!-- 要替换的部分 -->
</div>

在app.js完成获取和替换

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
const fs = require('fs');
const path = require('path');
const express = require('express')

function SSRServer(){
const app = express();

app.use("*",(req, res) => {

console.log("执行了app.use");
//在这里执行服务器渲染的工作

//实现思路,将真实数据替换到index.html中

//1. 读取index.html文件信息,作为模板
let template = fs.readFileSync(path.join(__dirname, "index.html"), "utf8");

//2. 获取真正的页面数据
const data = "<h1>真正的数据</h1>"

//3. 替换成真正的数据
const html = template.replace("<!-- 要替换的部分 -->",data);

//4. 返回给浏览器
res.send(html);
})

app.listen(3001,()=>{
console.log(`listening on http://localhost:3001`);
})
}

SSRServer()

image-20230307211523237

我们访问3001端口,可以看到真正的数据

四,在vite中配置ssr

1,准备工作

①创建vite项目

②在根目录中创建ssr-server.js

③安装express

④写出ssr-server.js大体框架,和前面的简单模拟中类似,此处我们需要注意使用vite的相关规定来配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
const express = require('express')

function ssrServer(){
const app = express()

app.use("*",(req,res)=>{
//有请求就会跑这段代码

//1. 读取index.html文件信息,作为模板---使用vite中间件模板化前端代码

//2. 获取真正的页面数据---从前端服务器获取

//3. 替换成真正的数据

//4. 返回给浏览器

})

app.listen(3009)
}

ssrServer()

2,改造项目入口文件

修改main.ts

1
2
3
4
5
6
7
8
9
10
import { createSSRApp } from 'vue'
import './style.css'
import App from './App.vue'

//createApp(App).mount('#app')
export default function createApp(){//需要导出
const app = createSSRApp(App)

return app
}

在src下创建现在的入口文件entry-client.ts

1
2
3
4
5
6
//配置新的入口文件
import createApp from "./main";

const app = createApp()

app.mount("#app")

3,渲染函数文件

在src下面创建render-func-server.ts渲染函数文件

1
2
3
4
5
6
7
8
9
10
//书写render函数
import createApp from './main'
import {renderToString} from 'vue/server-renderer';

export function render(url: string) {
const app = createApp()
//获取Vue最终处理完成的html
const html = renderToString(app)
return html
}

实现ssr-server.js的逻辑,别忘记现在index.html中添加占位符

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
const fs = require('fs');
const path = require('path');
const express = require('express')
const {createServer} = require('vite');

async function ssrServer(){
const app = express()

//获取vite的中间件,并注册到app项目下
const vite = await createServer({
server:{
middlewareMode: "ssr"
}
})
app.use(vite.middlewares)

app.use("*",async (req,res)=>{
//有请求就会跑这段代码

//1. 读取index.html文件信息,作为模板---使用vite中间件模板化前端代码
let template = fs.readFileSync(path.join(__dirname, "index.html"), "utf8");
template = await vite.transformIndexHtml(req.originalUrl, template)

//2. 获取真正的页面数据---从前端服务器获取
const {render} = await vite.ssrLoadModule("src/render-func-server.ts")
const appHtml = await render()

//3. 替换成真正的数据
const html = template.replace("<!-- 要替换的部分 -->",appHtml)

//4. 返回给浏览器
res.send(html)
})

app.listen(3009)
}

ssrServer()

4,挣扎的尝试

此时我们试着跑一下服务器代码

image-20230307215949427

按照提示将其转换为import即可

1
2
3
4
import { readFileSync } from 'fs';
import { join } from 'path';
import express from 'express';
import { createServer } from 'vite';

image-20230307220052366

我们还会发现这样一条错误,ssr被抛弃,要将其设置为true,appType设置为custom代替,这样更改

1
2
3
4
5
6
const vite = await createServer({
server:{
middlewareMode: "true"
},
appType:"custom"
})

大体的思路是这样,但是事实证明…可能是版本原因吧…调试了好久…跑不起来…T^T…于是我们来看看官网怎么配置

五,参考vite官网配置

官网地址:https://cn.vitejs.dev/guide/ssr.html

果然还得是官网…

image-20230308002535715