React ssr 服务器渲染

实现时间为2020年7月

这部分网上资料较少,而且用户库比较旧,没有特别好的解决方案,决定从头开始自己实现一套方案,express做服务端,前端为主流的 react + react router + redux;

首先用npx create-react-app app创建基本站点,不加入router和redux;
package.json里面的script加入:

"server": "nodemon --exec babel-node server/index.js",

用于启动服务器,同时配置babel,创建.babelrc代码:

{
  "presets": [
    [
      "@babel/preset-env",
      {
        "targets": {
          "node": "current"
        }
      }
    ],
    [
      "@babel/preset-react"
    ]
  ],
  "plugins": [
    "@babel/plugin-proposal-class-properties"
  ],
  "ignore":[
    "./src/public/"
  ]
}

babel-node是babel新版本提供的一个命令,用于node代码编译支持,这样通过import导入代码就不会出错,很多老的文章教程没有提到这个。

代码目录为:

image.png

主要实现server/index.js的内容

import express from 'express';
import compression from 'compression';
import { renderToString } from "react-dom/server";

require('@babel/register')();

require('@babel/polyfill')
require.extensions['.less'] = () => {
  return;
};
require.extensions['.css'] = () => {
  return;
};

const renderReact = require('./renderReact.js');

const router = express.Router();
import path from 'path';

const app = express();
app.use(compression());
renderReact(app);
app.use(express.static(path.resolve(__dirname, '../build/')))


const port = process.env.PORT || 4000;

app.listen(port, function listenHandler() {
  console.info(`Running on ${ port }`);
});

另外还有一个renderReact.js,为什么要分成两个,因为babel-register doesn't process the file it is called from, see https://stackoverflow.com/a/29425761/1795821
renderReact.js:

import React from 'react';
import fs from 'fs';
const reactDomServer = require('react-dom/server');
import App from "../src/App";

const renderPage = function(reactHtml){
  return reactHtml;
}

let buildHtml;

module.exports = function(app) {
  app.get('/', (req, res) => {
    const appHtml = reactDomServer.renderToString();
    if(!buildHtml){
      buildHtml = fs.readFileSync('./build/index.html','utf8');
    }
    let result = buildHtml.replace('#body', appHtml);
    console.log(buildHtml);
    console.log(appHtml);
    res.send(result)
  })
}

基本大功告成,最后在public的index.html里面加上#body方便替换成renderToString解析出来的dom代码。

#body

源码地址:https://github.com/liuxiaocong/react-ssr-2020

但是目前的操作只支持到js层面,其他资源类像css,image的都不支持,只能算阉割版的SSR,最近花了几天时间,终于实现了一个完整版的,可以看下这里的记录:https://www.jianshu.com/p/40654743a387

你可能感兴趣的:(React ssr 服务器渲染)