手动实现一个自己的 React 服务端渲染

勾勾的前端世界

共 3144字,需浏览 7分钟

 ·

2020-12-06 11:13

嗨,我是你稳定更新、持续输出的勾勾。今天的主题是 React 服务端渲染。



# 为什么要有服务端渲染?


框架开发是当前炙手可热的流行趋势,SPA 这种模式也被越来越多的人认可,但是随着研究的深入,一些问题就慢慢凸显出来了。


最重要的两点,一是首页需要等待;第二,不利于 SEO 。


为了解决这些问题,框架也推出了自己的解决方案——Server Side Rendering 服务端渲染


本篇文章咱们就以 React 为例,聊聊如何在 react 环境下手动实现一个 SSR ?


# 真枪实弹的第一步


首先,在项目下创建一个文件夹 src,在里面放置三个文件夹 client (客户端代码),common(共同的代码),server(服务端代码)。



这里 server 文件夹是我们关注的重点。在这个 server 文件夹下,我们需要创建一个 http.js 文件,内容如下,目的是启动一个服务。

//http.jsconst 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 就算完成了~


推荐阅读:

字节百度前端面试真题:异步处理方案(内附答案)

不会真的有人不知道 API 如何设计吧。

别再复制粘贴了!高效工作神器—— plop

API 终结者 —— 杀手 Reflect

前端人因为 Vue3 的 Ref-sugar 提案打起来了!

效率提升利器:你还害怕自动化部署吗

黑盒续集 | 如何在 CRA 黑盒中争取主动权?

基操勿 6 | Node.js 的异步I/O到底有多秀?


点点“”和“在看”,保护头发,减少bug。

浏览 51
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报