React 同构开发(二)

React 同构

所谓同构,简单的说就是客户端的代码能够在服务端运行,好处就是能极大的提高首屏时间,避免白屏,另外同构也给SEO提供了不少便利。css

React 同构得益于 React 的虚拟 DOM。虚拟 DOM 以对象树的形式保存在内存中,并存在先后端两种展示形式。html

  • 在客户端上,虚拟 DOM 经过 ReactDOM 的 render 方法渲染到页面中,造成真实的 dom。
  • 在服务端上,React 提供了另外两个方法: ReactDOMServer.renderToString 和 ReactDOMServer.renderToStaticMarkup 将虚拟 DOM 渲染为 HTML 字符串。

在服务端经过 ReactDOMServer.renderToString 方法将虚拟 DOM 渲染为 HTML 字符串,到客户端时,React 只须要作一些事件绑定等操做就能够了。node

在这一整套流程中,保证 DOM 结构的一致性是相当重要的一点。 React 经过 data-react-checksum来检测一致性,即在服务端产生 HTML 字符串的时候会额外的计算一个 data-react-checksum 值,客户端会对这个值进行校验,若是与客户端计算的值一致,则 React 只会进行事件绑定,若是不一致,React 会丢弃服务端返回的 dom 结构从新渲染。react

服务端对 ES6/7 的支持

React 新版本中已经在推荐采用 ES6/7 开发组件了,所以服务端对 ES6/7 的支持也不得不跟上咱们开发组件的步伐。可是如今 node 原生对 ES6/7 的支持还比较弱,这个时候咱们就须要借助于 babel 来完成 ES6/7 到 ES5 的转换。这一转换,咱们经过 babel-register 来完成。webpack

babel-register 经过绑定 require 函数的方式(require hook),在 require jsx 以及使用 ES6/7 编写的 js 文件时,使用 babel 转换语法,所以,应该在任何 jsx 代码执行前,执行 require('babel-register')(config),同时经过配置项config,配置babel语法等级、插件等。git

这里咱们给一个配置 demo, 具体配置方法可参看官方文档es6

{
  "presets": ["react", "es2015", "stage-0"],

  "plugins": [
    "transform-runtime",
    "add-module-exports",
    "transform-decorators-legacy",
    "transform-react-display-name"
  ],

  "env": {
    "development": {
      "plugins": [
        "typecheck",
        ["react-transform", {
            "transforms": [{
                "transform": "react-transform-catch-errors",
                "imports": ["react", "redbox-react"],
                "locals": ["module"]
              }
            ]
        }]
      ]
    }
  }
}

css、image 等文件服务端如何支持

通常状况来讲,不须要服务端处理非js文件,可是若是直接在服务端 require 一个非 js 文件的话会报错,由于 require 函数不认识非 js 文件,这时候咱们须要作以下处理, 已样式文件为例:github

var Module = require('module');
Module._extensions['.less'] = function(module, fn) {
  return '';
};
Module._extensions['.css'] = function(module, fn) {
  return '';
};

具体原理能够参考require 解读web

或者直接在 babel-register 中配置忽略规则:json

require("babel-register")({
  ignore: /(\.css|\.less)$/,
});

可是,若是项目中使用了 css_modules 的话,那服务端就必需要处理 less 等文件了。为了解决这个问题,须要一个额外的工具 webpack-isomorphic-tools,帮助识别 less 等文件。

简单地说,webpack-isomorphic-tools,完成了两件事:

  • 以webpack插件的形式,预编译less(不局限于less,还支持图片文件、字体文件等),将其转换为一个 assets.json 文件保存到项目目录下。
  • require hook,全部less文件的引入,代理到生成的 JSON 文件中,匹配文件路径,返回一个预先编译好的 JSON 对象。

构建

客户端的代码经过配置 webpack 打包发布到 CDN 便可。

经过配置 webpack 和 webpack-isomorphic-tools 将非 js 文件打包成 assets 文件便可。

相关文章
相关标签/搜索