1. 程式人生 > 其它 >手動實現一個自己的 React 服務端渲染

手動實現一個自己的 React 服務端渲染

技術標籤:React服務端渲染reactjs

為什麼要有服務端渲染?

框架開發是當前炙手可熱的流行趨勢,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(` //這是一個字串模板哦 <html> <head> <title>react-ssr</title> </head> <body> <div id="root">
${string}</div> </body> </html> `
) })

這裡面解釋幾個點:

  • renderToString 這個方法是專門將元件轉成字串格式的。

  • Home 是在 common 資料夾下建立的一個元件 Home.js,內容如下:

import React from "react"
function Home(){
    return (
        <div>hello world</div>
    )
}
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 就算完成了~