react&node - 服務端渲染(server-render&hydrate) 上

image.png

前言

本文章須要對react和koa而且webpack有必定的基礎javascript

相信你們對react或者是vue來講用的更多的是後臺管理或者是app之類的,這些應用每每直接一個cli就能夠搞定了 既然這樣,爲何官方還要出一個服務端渲染的支持呢?閒的沒事 固然不是,由於像某些面對用戶的web端,一般都要考慮一個東西,也就是seo 若是直接cli create的項目你們確定也都看過那個網站源代碼、空空如也,什麼都看不到,中國的大多數搜索引擎(好比百度)是不會看js的,因此這確定知足不了需求,可是服務端渲染一些經常使用的比方說ejs什麼這簡直就是原生、寫起來既慢又不舒服、那你們都是怎麼實現的呢? 本文章就來講說大廠目前服務端渲染的最優解決方案。前端

服務端渲染

在前端來講其實聽到這個詞應該沒有 混編 來的更多一點 爲何須要服務端渲染:vue

  1. 傳統webpack-cli打包無法作seo
  2. 首屏渲染優化能力有限
  3. 無法作靜態化(也就是訪問頻率搞的頁面提早生成好,請求的時候能直接甩過去、優化性能)

方案

其實後端渲染方案仍是挺多的,拿react來講,它其實有本身的解決方案好比:java

  1. next - 不成熟。
  2. 這是個react官放推薦的,可是說實話、出來的結果比較讓人失望
  3. 自帶很是多的東西、很不利於維護、並且很亂、並且對seo也沒有特別的友好
  4. 因此目前來講還遠遠沒有到能夠在大項目中用的成熟度
  5. 後臺渲染
  6. ejs ✅ 1. 其實後臺渲染的成熟的東西很是多,我我的比較喜歡ejs,不過都差不太多 1. 我們的我們的例子最終也是用ejs來配合react-server-render最終來渲染

這些是服務器渲染 還有就是react 怎麼和react-server-render渲染的這些東西怎麼來整合 由於後端渲染出去的東西都是死的,包括什麼事件都是沒有的,這確定不行node

存在的問題和難點預告

首先呢,你們都明白react有點特殊,用的不是js,而是jsx,而後平時的項目中你們也都是用webpack去編譯jsx的 可是呢、又有一個問題 在node裏寫jsx語法都通不過、可是webpack又無法去編譯node,由於node裏有一些系統自帶的模塊源碼根本打包不進來比方說 fs、http之類的 因此呢,我們採用的方案很簡單、給react那一套單獨配上jsx 至於服務的那一塊,根本不用想,各類系統包包括什麼多進程等等的webpack是打包不了的, 可是至於怎麼配合這個就是本篇文章說的重點react


react如何用於後臺渲染

建立項目

image.png 相似這樣 而後終端 cd ./react-server-render  而後執行 yarn init -y  或者 cnpm init -y webpack

下載依賴

yarn add koa react react-dom webpack web

文件建立

首先先建一個1.jsx放在 components目錄下 像這樣 image.png 而後隨便寫一個react組件npm

import React from 'react';

export default class App extends React.Component {
  render(){
    return (<div>app</div>)
  }
}
複製代碼

而後在根目錄建一個server.js後端

const Koa = require('koa');
const ReactDOMServer = require('react-dom/server')

let app = new Koa();

app.use(ctx=>{
	ctx.body = ???
})

app.listen(9000)
複製代碼

 而後呢?按着我們正常的思路如今走一遍,首先須要一個服務器,而後能夠先隨便給一個use請求什麼都返回這個就完了,注意這時候有問題了,要返回什麼? 直接nodejs裏是不能直接引入jsx的會報錯,我們能夠先來試一下

從react官網能夠看到 image.png

ReactDOMServer裏有一個renderToString方法,能夠把組件變成字符串,我們直接試一下

解決node中不能引入jsx問題

 server.js

const Koa = require('koa');
const ReactDOMServer = require('react-dom/server')
const Cp1 = require('./components/1');

let app = new Koa();

app.use(ctx=>{
  ctx.body = ReactDOMServer.renderToString(<Cp1 />)
})

app.listen(9000)
複製代碼

這時候運行會直接爆炸💥 image.png 我們上文中講過node中是不能直接寫jsx語法的

引入webpack編譯jsx

好的,既然這樣,我們就用我們親愛的webpack 安裝依賴

yarn add babel-loader @babel/core @babel/preset-react
複製代碼

新建一個webpack.config.js

const path=require('path');

module.exports={
  mode: 'development',
  entry: './libs/index',
  target: 'node',

  output: {
    libraryTarget: 'umd',
    path: path.resolve(__dirname, 'dist'),
    filename: 'main.js'
  },
  module: {
    rules: [
      {test: /\.jsx$/, exclude: /node_modules/, use: {
        loader: 'babel-loader',
        options: {
          presets: ['@babel/preset-react']
        }
      }}
    ]
  },
  resolve: {
    extensions: ['.js', '.jsx', '.ts', '.tsx'],
  }
};

複製代碼

我們這個文章不是主要講webpack的,直接貼代碼了就 你們看webpack配置應該也看到了,裏面的entry是 libs/index 沒錯,我們須要一個單獨的目錄來區分一下,哪些是react項目,哪些是node項目 而後再建一個 index.jsx放到libs下  /libs/index.tsx

const React=require('react');
const ReactDOMServer=require('react-dom/server');
const App=require('../components/1');

module.exports=function render(){
  return ReactDOMServer.renderToString(<App />);
}

複製代碼

這個時候,咱們來編譯一下

webpack
複製代碼

就會看到這樣的結果 image.png

而後改我們server.js

const Koa = require('koa');
const { render } = require('./dist/main');

let app = new Koa();

app.use(async ctx => {
  let str = render();

  ctx.body = str;
});

app.listen(8000);

複製代碼

 /components/1.jsx

import React from 'react';

export default class App extends React.Component {
  constructor(props){
    super(props)
  }
  render(){
    return (<div>app</div>)
  }
}
複製代碼

而後 webpack 一下 而後運行我們的server.js node server.js 而後訪問 http://localhost:8000/ image.png 就會看到我們想要的結果了

而且點擊右鍵查看源碼 image.png 能夠看到真正的元素了,再也不是想以前cli建立的同樣只有一個 <div id="app"></div> 了

總結

我們本篇文章已經說了react單純配合koa作服務端渲染是什麼樣的感受了 不過還遠遠不夠,原本我打算一篇文章寫完的,結果發現東西有點多 我們目前還有不少不少的問題沒說 好比如今只是單純的渲染出來了、也都是好使的,

  1. 那服務端koa給的數據應該怎麼傳到react裏,
  2. 包括服務端渲染這一塊渲染出去的都是靜態的,沒有事件,那這個確定不行
  3. 還有作了靜態化的網站是怎麼二次用react.hydrate進行二次渲染
  4. 還有就是怎麼配合ejs等等等等

看你們對這東西敢不敢興趣了,感興趣的話我能夠接着再出react服務端渲染第二章

有什麼感興趣的,或者遇到什麼問題能夠直接加我好友,我們一塊兒溝通

微信:Dyy916829411 qq: 916829411

相關文章
相關標籤/搜索