React SSR(服务器端渲染) 细微探究

最近看了下 React SSR相关的东西,这里记录一下相关内容

本文实例代码已经上传到 github,感兴趣的可参见 Basic | SplitChunkV

初识 React SSR

nodejs遵循 commonjs规范,文件的导入导出如下:

// 导出
module.exports = someModule
// 导入
const module = require('./someModule')

而我们通常所写的 react代码是遵循 esModule规范的,文件的导入导出如下:

// 导出
export default someModule
// 导入
import module from './someModule'

所以想要让 react代码兼容于服务器端,就必须先解决这两种规范的兼容问题,实际上 react是可以直接以 commonjs规范来书写的,例如:

const React = require('react')

这样一看似乎就是个写法的转换罢了,没什么问题,但实际上,这只是解决了其中一个问题而已,react中常见的渲染代码,即 jsxnode是不认识的,必须要编译一次

render () {
   
  // node是不认识 jsx的
  return <div>home</div>
}

客户端编译 react代码用到最多的就是 webpack,服务器端同样可以使用,这里使用 webpack的作用有两个:

  • jsx编译为 node认识的原生 js代码
  • exModule代码编译成 commonjs

webpack示例配置文件如下:

// webpack.server.js
module.exports = {
   
  // 省略代码...
  module: {
   
    rules: [
      {
   
        test: /\.js$/,
        loader: 'babel-loader',
        exclude: /node_modules/,
        options: {
   
          // 需要支持 react
          // 需要转换 stage-0
          presets: ['react', 'stage-0', ['env', {
   
            targets: {
   
              browsers: ['last 2 versions']
            }
          }]]
        }
      }
    ]
  }
}

有了这份配置文件之后,就可以愉快的写代码了

首先是一份需要输出到客户端的 react代码:

import React from 'react'

export default () => {
   
  return <div>home</div>
}

这份代码很简单,就是一个普通的 react stateless组件

然后是负责将这个组件输出到客户端的服务器端代码:

// index.js
import http from 'http'
import React from 'react'
import {
    renderToString } from 'react-dom/server'
import Home from './containers/Home/index.js'

const container = renderToString(<Home />)

http.createServer((request, response) => {
   
  response.writeHead(200, {
   'Content-Type': 'text/html'})
  response.end(`
    <!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="root">${
     container}</div>
    </body>
    </html>
  `)
}).listen(8888)

console.log('Server running at http://127.0.0.1:8888/')

上述代码就是启动了一个 node http服务器,响应了一个 html页面源码,只不过相比于常见的 node服务器端代码而言,这里还引入了 react相关库

我们通常所写的 React代码,其渲染页面的动作,其实是 react调用浏览器相关 API实时进行的,即页面是由 js操纵浏览器DOM API组装而成,服务器端是无法调用浏览器 API的,所以这个过程无法进行,这个时候就需要借助 renderToString

renderToStringReact提供的用于将 React代码转换为浏览器可直接识别的 html字符串的 API,可以认为此 API提前将浏览器要做的事情做好了,直接在服务器端将DOM字符串拼凑完成,交给 node输出到浏览器

上述代码中的变量 container,其实就是如下的 html字符串:

<div data-reactroot="">home</div
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值