服务端渲染服务端渲染(SSR)主要是为了SEO,加快首屏的加载速度等作用。利用react-dom/server提供的工具,我们很容易进行服务端渲染。基本原理服务端渲染的基本原理就是读取我们的模板文件,然后将其中的内容替换成我们自己的代码,然后生成一个完整的html文件返回给前端页面。webpack配置在第一篇文章中,已经进行了基础的配置,本文是在前面的基础上来配置的。本次配置需要安装以下两个依赖express, 涉及到服务端代码,用到express包rimraf, 看着名字就知道是删库跑路的包。每次我们运行build命令时,都会生成新的文件。我们可以用这个包先删除dist目录,然后在重新生成新的dist目录。首先在client目录下新增template.html和server-entry.js两个文件。前面的html时模板文件,后面的js作为服务端的入口文件。// template文件很简单,只有一个id为app的div,后面我们将会把<!– <app /> –>替换为我们自己的内容。<!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> <div id=“app”><!– <app /> –></div></body></html>// 入口文件目前也很简单,只是导入App组件import React from ‘react’import App from ‘./App.jsx’export default <App />在build目录下新增webpack.config.server.js文件,作为服务端打包的配置文件。同时为了区分客户端,将客户端的配置文件改为webpack.config.client.js。服务端与客户端的配置基本一样,主要时入口文件和出口文件的配置不同。 entry: { app: resolvePath(’../client/server-entry.js’) // 服务端入口文件 }, output: { filename: ‘server-entry.js’, // 输出文件名 path: resolvePath(’../dist’), // 输出路劲 publicPath: ‘’, // libraryTarget: ‘commonjs2’ // 模块化的方式 },在项目目录下新建server文件夹,新建一个server.js文件,该文件主要为服务端逻辑。const express = require(’express’)const ReactSSR = require(‘react-dom/server’)const fs = require(‘fs’)const path = require(‘path’)const serverEntry = require(’../dist/server-entry’).default // 打包好的服务端文件const app =express()const template = fs.readFileSync(path.join(__dirname, ‘../dist/index.html’), ‘utf-8’) // 读取模板文件app.get(’*’, function(req, res) { const appString = ReactSSR.renderToString(serverEntry) res.send(template.replace(’<!– <app /> –>’, appString)) // 将模板文件中的注释替换为我们自己的内容,然后返回到客户端})app.listen(3333, function() { console.log(‘server is listen on 3333’)})服务端渲染的基本逻辑就已经完成。接下来我们在package.json文件中新增一些命令。 “scripts”: { “build:client”: “webpack –config build/webpack.config.client.js”, // 编译客户端代码 “build:server”: “webpack –config build/webpack.config.server.js”, // 编译服务端代码 “clear”: “rimraf dist”, // 每次build前,先自动删除dist目录 “build”: “npm run clear && npm run build:client && npm run build:server”,// build客户端和服务端的代码 “start”: “node server/server.js” // 启动服务器 },先运行build命令,然后运行start命令,访问localhost:3333,就可以看到内容了。而且在network窗口中可以看到返回的时完整的html页面,而不是一个空页面。但时目前请求js文件,返回的也是html文件。因为在server.js中,任意的请求都是返回html文件。可以通过express来配置静态文件目录。// 以/public开头的请求都会去dist目录中找。app.use(’/public’, express.static(path.join(__dirname, ‘../dist’)))同时需要修改客户端和服务端的webpack配置。 // 会在路径前加上/public前缀 output: { publicPath: ‘/public’, },重新运行build和start命令,访问3333端口,就会返现请求都是正常的。从返回的html文件中,script标签的src属性中的路径会带有/public前缀,这就是publicPath属性的作用。至此,服务端渲染的基础配置就已经完成。本次的代码位于仓库的2-5分支。在使用rimraf时,window可能会遇到一些权限相关的问题,可能的解决方法点这里