React 同構開發(二)


React 同構

所謂同構,簡單的說就是客戶端的代碼可以在服務端運行,好處就是能極大的提升首屏時間,避免白屏,另外同構也給SEO提供了很多便利。

React 同構得益於 React 的虛擬 DOM。虛擬 DOM 以對象樹的形式保存在內存中,並存在前后端兩種展現形式。

  • 在客戶端上,虛擬 DOM 通過 ReactDOM 的 render 方法渲染到頁面中,形成真實的 dom。
  • 在服務端上,React 提供了另外兩個方法: ReactDOMServer.renderToString 和 ReactDOMServer.renderToStaticMarkup 將虛擬 DOM 渲染為 HTML 字符串。

在服務端通過 ReactDOMServer.renderToString 方法將虛擬 DOM 渲染為 HTML 字符串,到客戶端時,React 只需要做一些事件綁定等操作就可以了。

在這一整套流程中,保證 DOM 結構的一致性是至關重要的一點。 React 通過 data-react-checksum來檢測一致性,即在服務端產生 HTML 字符串的時候會額外的計算一個 data-react-checksum 值,客戶端會對這個值進行校驗,如果與客戶端計算的值一致,則 React 只會進行事件綁定,如果不一致,React 會丟棄服務端返回的 dom 結構重新渲染。

服務端對 ES6/7 的支持

React 新版本中已經在推薦采用 ES6/7 開發組件了,因此服務端對 ES6/7 的支持也不得不跟上我們開發組件的步伐。但是現在 node 原生對 ES6/7 的支持還比較弱,這個時候我們就需要借助於 babel 來完成 ES6/7 到 ES5 的轉換。這一轉換,我們通過 babel-register 來完成。

babel-register 通過綁定 require 函數的方式(require hook),在 require jsx 以及使用 ES6/7 編寫的 js 文件時,使用 babel 轉換語法,因此,應該在任何 jsx 代碼執行前,執行 require('babel-register')(config),同時通過配置項config,配置babel語法等級、插件等。

這里我們給一個配置 demo, 具體配置方法可參看官方文檔

{
  "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 文件,這時候我們需要做如下處理, 已樣式文件為例:

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

具體原理可以參考require 解讀

或者直接在 babel-register 中配置忽略規則:

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 文件即可。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM