react服務端渲染
說明
近期一直想看看react項目ssr到底是怎麼做的,最近一直在學習,研究如何從零到一的實現react的服務端渲染,並將整個過程的代碼整理出來,作爲參考
- react項目重構
- 項目中使用了koa和express,主要是學習,如果項目中可以使用koa或者express
初始化一個項目
這裏主要是實現基本的模擬代碼,項目中我們通常會在原來的項目基礎上做處理
- 新建一個目錄
npm init
創建基本目錄
這裏主要是新建基本的文件和目錄,方便後期在內部處理代碼
- 新建src目錄
- 新建webpack.config.js
基本的解構代碼
- src目錄下新建containers目錄
- src/containers目錄下新建Header, Home兩個目錄
- 在Header, Home兩個目錄下新建index.js, 內容如下
// Header/index.js
import React from 'react'
function Header () {
return (<header>
header
</header>)
}
export default Header
// Home/indes.js
import React, {Component} from 'react';
function Home () {
return (<h1>Home</h1>)
}
export default Home;
入口文件處理
這裏不是我們我們原來的樣子 ,因爲服務端渲染, 所以我們需要寫一個服務器,
其次就是服務端返回的是字符串,我們急需要藉助renderToString方法講react組件轉換爲字符串, 然後返回
- src目錄下新建server目錄, 並在Server目錄內部新建index.js文件愛你
- src/server/index.js 中書寫如下內容
let Koa = require('koa')
import React from 'react'
import Home from '../containers/Home/index'
import Header from '../containers/Header/index'
import {renderToString} from 'react-dom/server'
// renderToString:react-dom 方法,講react組件渲染爲字符串
let app = new Koa()
app.use(async function (ctx, next) {
// 轉義組件爲字符串
let html = renderToString(<Home />)
let head = renderToString(<Header />)
ctx.body = `
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
${head}
${html}
</body>
</html>
`
})
app.listen(3000)
配置打包環境 (webpack)
這裏的配置就是webpack的基本配置,沒有什麼好說的
// package.json 中的配置
"scripts": {
"dev": "npm-run-all --parallel dev:**",
"dev:build": "webpack --config webpack.config.js --watch", // 運行webpack ,--watch 文件改動自動打包
"dev:start": "nodemon build/server.js" // 配置自動刷新
},
// webpack.config.js 中的配置
const path = require('path')
const nodeExternal = require('webpack-node-externals')
module.exports = {
target: 'node', // 告訴webpack 打包的是node環境的
mode: 'development',
// entry: './src/server/index.js', // 提示
entry: ['babel-polyfill', './src/server/index.js'],
output: {
filename: 'server.js',
path: path.join(__dirname,'build')
},
// 負責檢測所有引入不得node的核心模塊,並且通知webpack不需要將核心代碼打入到server.js 文件中去
externals: [nodeExternal()],
module: {
rules: [
{
test: /\.js$/,
loader: 'babel-loader',
exclude: /node_modules/,
options: {
presets: [
'@babel/preset-env',
'@babel/preset-react'
]
}
}
]
}
}
配置自動刷新
依賴nodemon實現自動刷新
"scripts": {
"dev": "npm-run-all --parallel dev:**",
"dev:build": "webpack --config webpack.config.js --watch",
"dev:start": "nodemon build/server.js" // 配置自動刷新
},
- 配置批量運行命令 (依賴 npm-run-all)
"scripts": {
"dev": "npm-run-all --parallel dev:**", // 配置批量運行命令
"dev:build": "webpack --config webpack.config.js --watch",
"dev:start": "nodemon build/server.js"
},
總結
到這裏就實現了最基本的配置,文件目錄,webpack打包