手動實現一個自己的 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(` //這是一個字串模板哦
<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 就算完成了~