龙空技术网

说说React服务端渲染怎么做?

咸鱼养成记 119

前言:

当前我们对“react 后端渲染”大体比较着重,同学们都想要分析一些“react 后端渲染”的相关文章。那么小编也在网摘上搜集了一些对于“react 后端渲染””的相关资讯,希望小伙伴们能喜欢,大家一起来了解一下吧!

在SSR中,我们了解到Server-Side Rendering ,简称SSR,意为服务端渲染

指由服务侧完成页面的 HTML 结构拼接的页面处理技术,发送到浏览器,然后为其绑定状态与事件,成为完全可交互页面的过程

其解决的问题主要有两个:

SEO,由于搜索引擎爬虫抓取工具可以直接查看完全渲染的页面加速首屏加载,解决首屏白屏问题

在react中,实现SSR主要有两种形式:

手动搭建一个 SSR 框架使用成熟的SSR 框架,如 Next.JS

这里主要以手动搭建一个SSR框架进行实现

首先通过express启动一个app.js文件,用于监听3000端口的请求,当请求根目录时,返回HTML,如下:

const express = require('express')const app = express()app.get('/', (req,res) => res.send(`<html>   <head>       <title>ssr demo</title>   </head>   <body>       Hello world   </body></html>`))app.listen(3000, () => console.log('Exampleapp listening on port 3000!'))

然后再服务器中编写react代码,在app.js中进行应引用

import React from 'react'const Home = () =>{    return <div>home</div>}export default Home

为了让服务器能够识别JSX,这里需要使用webpakc对项目进行打包转换,创建一个配置文件webpack.server.js并进行相关配置,如下:

const path = require('path')    //node的path模块const nodeExternals = require('webpack-node-externals')module.exports = {    target:'node',    mode:'development',           //开发模式    entry:'./app.js',             //入口    output: {                     //打包出口        filename:'bundle.js',     //打包后的文件名        path:path.resolve(__dirname,'build')    //存放到根目录的build文件夹    },    externals: [nodeExternals()],  //保持node中require的引用方式    module: {        rules: [{                  //打包规则           test:   /\.js?$/,       //对所有js文件进行打包           loader:'babel-loader',  //使用babel-loader进行打包           exclude: /node_modules/,//不打包node_modules中的js文件           options: {               presets: ['react','stage-0',['env', {                                   //loader时额外的打包规则,对react,JSX,ES6进行转换                    targets: {                        browsers: ['last 2versions']   //对主流浏览器最近两个版本进行兼容                    }               }]]           }       }]    }}

接着借助react-dom提供了服务端渲染的 renderToString方法,负责把React组件解析成html

import express from 'express'import React from 'react'//引入React以支持JSX的语法import { renderToString } from 'react-dom/server'//引入renderToString方法import Home from'./src/containers/Home'const app= express()const content = renderToString(<Home/>)app.get('/',(req,res) => res.send(`<html>   <head>       <title>ssr demo</title>   </head>   <body>        ${content}   </body></html>`))app.listen(3001, () => console.log('Exampleapp listening on port 3001!'))

上面的过程中,已经能够成功将组件渲染到了页面上

但是像一些事件处理的方法,是无法在服务端完成,因此需要将组件代码在浏览器中再执行一遍,这种服务器端和客户端共用一套代码的方式就称之为同构

重构通俗讲就是一套React代码在服务器上运行一遍,到达浏览器又运行一遍:

服务端渲染完成页面结构浏览器端渲染完成事件绑定

浏览器实现事件绑定的方式为让浏览器去拉取JS文件执行,让JS代码来控制,因此需要引入script标签

通过script标签为页面引入客户端执行的react代码,并通过express的static中间件为js文件配置路由,修改如下:

import express from 'express'import React from 'react'//引入React以支持JSX的语法import { renderToString } from'react-dom/server'//引入renderToString方法import Home from './src/containers/Home' const app = express()app.use(express.static('public'));//使用express提供的static中间件,中间件会将所有静态文件的路由指向public文件夹 const content = renderToString(<Home/>) app.get('/',(req,res)=>res.send(`<html>   <head>       <title>ssr demo</title>   </head>   <body>        ${content}   <script src="/index.js"></script>   </body></html>`)) app.listen(3001, () =>console.log('Example app listening on port 3001!'))

然后再客户端执行以下react代码,新建webpack.client.js作为客户端React代码的webpack配置文件如下:

const path = require('path')                    //node的path模块module.exports = {    mode:'development',                         //开发模式    entry:'./src/client/index.js',              //入口    output: {                                   //打包出口        filename:'index.js',                    //打包后的文件名        path:path.resolve(__dirname,'public')   //存放到根目录的build文件夹    },    module: {        rules: [{                               //打包规则           test:   /\.js?$/,                    //对所有js文件进行打包           loader:'babel-loader',               //使用babel-loader进行打包           exclude: /node_modules/,             //不打包node_modules中的js文件           options: {               presets: ['react','stage-0',['env', {                         //loader时额外的打包规则,这里对react,JSX进行转换                    targets: {                        browsers: ['last 2versions']   //对主流浏览器最近两个版本进行兼容                    }               }]]           }       }]    }}

标签: #react 后端渲染 #react渲染过程