react服务端渲染

服务端渲染

前期准备工作

我们首先新建一个文件夹用于存放所有文件

> mkdir reacr-server-side-rendering

接着我们初始化npm包,初始化完成之后,我们需要安装以下npm包以便我们开发服务端渲染实例。

> npm init
> npm i react,..... --save
  • react UI框架
  • express 服务端框架
  • react-dom react转换成字符串
  • react-transmit 提前执行请求,本次项目中未使用
  • babel-cli 编译
  • babel-loader
  • babel-preset-es2015
  • babel-preset-react

安装完成之后,由于我们使用的是babel-cli集成的babel-node工具,那么我们需要配置babel的编译选项.

需要设置.babelrc 设置编译react

{
  "presets": ["react", "es2015"]
}

编写React组件

由于我们只是做一个Demo展示,所以我们简单的进行文件架构。如果你们应用在实际项目中,请根据自身项目进行配置。

我们首先创建一个首页展示组件,代码如下。

Index.js
import React from 'react';
import ButtonNormal from './ButtonNormal';

export default class Index extends React.Component {

    constructor () {
        super()
    };
    componentWillMount () {}
    componentDidMount  () {}
    shouldComponentUpdate () {return true;}
    componentWillUpdate () {}
    componentDidUpdate () {}
    componentWillUnmount () {}

    render () {
        return (<div>
            <h1>这是一个服务端渲染的react组件</h1>
            <p>
                <ButtonNormal>我是一个按钮</ButtonNormal>
            </p>
            <p>
                <ButtonNormal />
            </p>
        </div>);
    }
}

另外我们做了一点简单的组件引用,我们再次创建一个名为ButtonNormal.js文件。

ButtonNormal.js

import React, {Component} from 'react';

export default class ButtonNormal extends Component {

    constructor (props) {
        super(props);
        this.state={
            text:props.children||props.text||'确定'
        }
    };
    componentWillMount () {}
    componentDidMount  () {}
    shouldComponentUpdate () {return true;}
    componentWillUpdate () {}
    componentDidUpdate () {}
    componentWillUnmount () {}

    render () {
        return (
            <button>{this.state.text}</button>
        );
    }
}

编写服务端渲染代码

我们已经完成了React的组件编写,那么我们现在需要进行服务端渲染的开发了。下面就是服务端代码。

const express = require('express');
const fs = require('fs');
const path = require('path');
const React = require('React');
const ReactDOMServer = require('react-dom/server');
const Index = require('./app/index').default;

const app = express();

// 使用我们的 handleRender 中间件处理服务端请求
app.get('*', (req, res)=> {
    // 把 Hello 组件渲染成 HTML 字符串
    // console.log(Index);
    // const html = ReactDOMServer.renderToStaticMarkup(React.createElement(Index.default));
    const html = ReactDOMServer.renderToString(<Index/>);
    // 加载 index.html 的内容
    fs.readFile(__dirname + '/app/templates/index.html', 'utf8', function (err, data) {
        if (err) throw err;

        // 把渲染后的 React HTML 插入到 div 中
        const document = data.replace(/<div id="app"><\/div>/, `<div id="app">${html}</div>`);

        // 把响应传回给客户端
        res.send(document);
    });
});

// 启动服务器
app.listen(3101);

服务端渲染的原理就是通过ReactDOM读取渲染完成的html字符串,然后将字符串替换进现有的服务端文件模版中,最后输出至客户端进行渲染。
这个操作也就是我们将之前的前端渲染逻辑放置在后端进行处理。由于前端技术日新月异,所以,具体将渲染放置在哪一步由具体的业务决定。

require('./app/index').default
由于我们采用了babel-node运行,require进入的文件是一个object,所以我们直接将默认default的方法进行赋值。

运行项目

配置package.json文件,在scripts中增加开发配置

    "dev": "babel-node ./src/server.js"

打开命令行环境,运行npm run dev

项目已上传至 GitHub - yodfz/react-server-side-rendering: react服务端渲染

参考文章

前端

摄影爱好者,全栈工程师,游戏玩家,积木苦手,超穷手办收藏爱好者

发表评论