手动实现一个自己的 React 服务端渲染
嗨,我是你稳定更新、持续输出的勾勾。今天的主题是 React 服务端渲染。
# 为什么要有服务端渲染?
框架开发是当前炙手可热的流行趋势,SPA 这种模式也被越来越多的人认可,但是随着研究的深入,一些问题就慢慢凸显出来了。
最重要的两点,一是首页需要等待;第二,不利于 SEO 。
为了解决这些问题,框架也推出了自己的解决方案——Server Side Rendering 服务端渲染。
本篇文章咱们就以 React 为例,聊聊如何在 react 环境下手动实现一个 SSR ?
# 真枪实弹的第一步
首先,在项目下创建一个文件夹 src,在里面放置三个文件夹 client (客户端代码),common(共同的代码),server(服务端代码)。
这里 server 文件夹是我们关注的重点。在这个 server 文件夹下,我们需要创建一个 http.js 文件,内容如下,目的是启动一个服务。
//http.js
const express = require("express")
const app = express()
app.listen(3000,function(){console.log("server is runing")})
export default app;
同时再添加一个 index.js 文件,内容如下。拆分两个文件的目的是为了保证服务代码和业务代码分离。
import app from "./http"
import React from "react"
import {renderToString} from "react-dom/server" //将组件转成字符串格式
import Home from "../common/Home"
app.get("/",function(req,res){
const string = renderToString(<Home>Home>) //
res.send(` //这是一个字符串模板哦
react-ssr
${string}
`)
})
这里面解释几个点:
renderToString 这个方法是专门将组件转成字符串格式的。
Home 是在 common 文件夹下创建的一个组件 Home.js,内容如下:
import React from "react"
function Home(){
return (
<div>hello worlddiv>
)
}
export default Home;
注意:
如果我们直接使用 Node 来启动服务,会报语法性错误,错误原因:
Node 下不支持 ESModule 语法
Node 下不支持 React 中的 JSX 语法
所以我们需要引入 webpack 进行打包,然后再启动服务。
# Webpack 配置
我们在项目下创建一个 webpack.server.js,内容如下:
const path = require("path")
module.exports = {
mode:"none",
target:"node",
entry:"./src/server/index.js",
output:{
path:path.join(__dirname,"dist"),
filename:"build.js"
},
module:{
rules:[
{
test:/\.js$/,
exclude:/node_modules/,
use:{
loader:"babel-loader",
options:{
presets:['@babel/preset-env','@babel/preset-react']
}
}
}
]
}
}
注意,我们需要安装 webpack webpack-cli。
对于 js 文件,我们需要使用 babel-loader,把它交给 babel 处理,所以要下载
Babel-loader @babel/core @babel/preset-env @babel/preset-react。
接下来配置 options,添加预设 presets。
# Webpack 打包
配置文件完成之后,我们需要打包,打包指令就是 npx webpack -- config webpack.server.js。对于这种打包指令很麻烦,我们需要在 package.json 中配置一个自己用的顺手的指令,修改如下:
//package.json
{
"name": "react-ssr",
"version": "1.0.0",
"description": "",
"main": "main.js",
"scripts": {
"dev:server-build":"npx webpack --config webpack.server.js"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"@babel/core": "^7.12.9",
"@babel/preset-env": "^7.12.7",
"@babel/preset-react": "^7.12.7",
"babel-loader": "^8.2.2",
"express": "^4.17.1",
"react": "^17.0.1",
"react-dom": "^17.0.1",
"webpack": "^5.9.0",
"webpack-cli": "^4.2.0"
}
}
当 npm run dev 一打包,就会出现一个 dist 文件夹,里面有个 build.js 文件。
Node 启动服务
最后,我们在终端使用 node dist/build.js 就可以直接启动这个文件。在网页中输入对应的 url,就会显示一个我们手动实现的服务端渲染案例,但这个页面是一个纯静态的页面。
至此,实现一个 React 的 SSR 就算完成了~
推荐阅读:
前端人因为 Vue3 的 Ref-sugar 提案打起来了!
点点“赞”和“在看”,保护头发,减少bug。