手写SSR
2022-6-11前提
写一篇全网最简单的手写ssr的文章,能看见,都靠缘分,毕竟本人很懒, 然后纯手打,传递概念,也没有商业用途,拜托喜欢挑刺命名啊等等的吹毛求疵,喜欢pua大佬离我远点,我谢谢你了,别看。。。
还有来找我博客网站的bug的大佬,我就是用hexo生成,有bug我就不改,就问你气不气?哈哈哈哈😂
关于SSR
相信很多人做seo都会用到SSR吧,对,曾今几年前我也做过2个nuxt.js 的项目,但是没有研究过原理。如今出现了SSG,ISR,DPR,不了解查一下,不缀述了。
关于SSR框架
Universal/nuxt/next/ice/VitePress 等等,轮子造的非常好对吧,商用的产品也不少,但是跟umi一样,打包后都会有框架代码,大堆api,至少也有几天的学习成本吧,
最最最重要的喜欢折腾的程序员喜欢极客,喜欢高定。。。但是诸多概念,设计,模型,性能,扩展性…..等等等,产出一个可以满足公司商用的SSR框架,可比单纯的一个
webpack脚手架可难多了,可是想成为专家,架构师,由兴趣驱动来做这件事不也相当nice吗?
手写SSR原理
由于我比较熟悉react,所以在react上面+ssr来记录下原理吧。
前置知识点:ReactDom.hydrate, react-dom/server/renderToString
先总结原理:
1.把client代理利用webpack+hydrate 打包起来,为水合js作准备。
2.利用renderToString在server生成html,为水合基座页面。
client:
// index.js
function App() {
return <p>利用水合反应向react的SSR注入js</p>
}
ReactDom.hydrate(App, document.getElementById('root'))
// webpack.client.js
const path = require('path')
module.exports = {
mode: "development",
entry: './src/index.js',
output: {
filename: 'dist.js',
path: path.resolve(__dirname, 'public')
},
module: {
rules: [
{
test: /\.js$/,
loader: 'babel-loader',
exclude: /node_modules/,
options: {
presets: ['@babel/preset-react', ['@babel/preset-env']]
}
}
]
}
}
server:
// index.js
import path from 'path'
import React from 'react'
import { renderToString } from 'react-dom/server'
import express from 'express'
const app = express()
app.use(express.static('public'))
const App=()=>{
return '服务端渲染静态内容'
}
app.get('/', (req, res) => {
const content = renderToString(<App />)
res.send(`
<html>
<head>
<meta charset="utf-8"/>
</head>
<body>
<div id="component">${content}</div>
<div id="root"></div>
<script src="/bundle.js"></script>
</body>
</html>`)
})
app.listen(8888, () => {
console.log(666)
})
//webpack.server.js
// 参考webpack.client.js ,server也需要用babel处理的
接下来跑起来或者用nginx试试吧
扩展
妥妥跟mvvm一样,属于系统内架构。
欢迎有兴趣的伙伴来联系我,我们可以一起拓展,来写:
- SSG,ISG,DPR 模式,搭配monorepo,搭配微服务等。
- 开源基础模式。
- 针对行业,高定商用框架。
也许在未来我也会一个人去做这件事…