小哥哥, React-SSR 要不要了解下-基礎篇

圈圈Dei圈發表於2019-07-12

我們也不知道這會兒寫這個出來算不算過時, 反正就想寫寫. 至於有沒有人看, 看完點不點贊, 點完贊會不會實踐. 我們也不敢問呀, 隨手寫寫吧~

2019-06-24-16-44-54

到了 9102 年, 作為前端扛把子的 React 依然炙手可熱. 周邊的各種生態更是紅的發燙. 每天應付完各種業務需求真的想舒舒坦坦躺上一波...

2019-06-24-17-12-03

偏偏又來了網際網路寒冬的夾持, 苦逼的前端 ?只能把這句不怎麼當講的話埋在心底了~

2019-06-24-17-13-37

這一期, 和大家一同學習 React + Koa 的服務端渲染知識. 文中不免疏漏, 望大佬斧正. 廢話不多說, 搞起來~

6af89bc8gw1f8ss9thu1sg20a305janv

首先, 還是要先配一個舒服的開發環境

配置開發環境參考這裡, 由於我們們建立的是 React 專案, 所以按照這篇文章配置到 eslint 就可以了.

ps: 最新版本的 eslint 更新後和那篇文章命令列步驟有點不一樣. 但是總體大同小異. 如果不想解決差異的同學可以安裝 eslint 5.9.0 這個版本, 保證和文章中一致性~

以上幾步操作的步驟為:

init

Hello world

首先我們建立一個基礎的 react 專案, 為了便於理解, 這裡不用 create-react-app, 而是直接用 webpack 手擼配置. 所以需要大家有一點點的 webpack 基礎知識. 如果實在沒有也沒關係, 我們們講~

開發環境建立完成後我們看到的專案結構應該新增了 package.json.eslintrc.js 兩個配置檔案還有一個 node_modules 目錄. 接下來就是我們大幹一場的時間啦~

2019-06-24-17-39-11

  • 首先, 在專案的根目錄建立一個 index.js
  • 編寫 index.js 檔案, 檔案內容如下.
console.log('hello world')
複製程式碼
  • 到了這一步開啟我們的命令列, 輸入命令 node index.js 回車
    success

恕我直言, 在座各位都已經晉級為 node.js 開發工程師了~

9150e4e5gy1g08qehjq9dg206j06j0tx

起步, React 版本的 HelloWorld

  • 首先安裝 React ReactDOM npm i react react-dom
  • 搭建專案目錄如下
    2019-07-11-18-42-03
    其中, src 目錄為專案原始碼目錄, client.js 檔案為客戶端渲染的入口檔案, components 目錄下的檔案為 react 元件檔案.
  • 建立並編寫 App.jsx 檔案
export default class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {};
  }

  render() {
    return (
      <div className="ssr-show">
        <h1>歡迎來到澳門皇冠賭場</h1>
      </div>
    );
  }
}
複製程式碼
  • 編寫 client.js 檔案
import React from 'react';
import ReactDOM from 'react-dom';
import App from './components/App';

// eslint-disable-next-line
ReactDOM.render(<App />, document.getElementById('app'));
複製程式碼

到了這一步, 似乎是沒有啥問題了, 但是, 這個東西跑不起來呀...

2019-07-11-19-02-42

之前的步驟根本沒有 html 作為依託, 我們們的專案更本就是不好使的. 此時的程式碼在 這裡 建議大家下載下來嘗試配置下 webpack

配置 webpack

配置 webpack 其實灰常簡單, 只需要三步.

  • 配置入口和輸出
  • 限定編譯規則
  • 生成 html 檔案託管打包成果

根據三步原理建立的 webpack 配置檔案如下

const path = require('path');
const HtmlWebPackPlugin = require('html-webpack-plugin');

module.exports = {
  // 客戶端渲染的入口檔案
  entry: './src/client.js',
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'bundle.js',
  },
  module: {
    // 因為目前我們的專案裡邊只有 js 和 jsx 檔案, 所以只配這一條規則就可以啦~
    rules: [
      {
        test: /\.jsx?$/,
        exclude: /node_modules/,
        use: {
          loader: 'babel-loader',
          options: {
            presets: ['@babel/preset-env', '@babel/preset-react'],
          },
        },
      },
    ],
  },
  plugins: [
    // 使用 html webpack plugin 建立 html 檔案作為專案產出的依託檔案
    new HtmlWebPackPlugin({
      template: './index.temp.html',
    }),
  ],
};
複製程式碼

最後新增 npm scriptpackage.json 的 script 欄位下新增以下程式碼 "build:client": "webpack --mode=production"

2019-07-11-19-33-46

最後執行 npm run build:client 結束後用你喜歡的瀏覽器開啟 index.html 檔案.

2019-07-11-19-35-45

進行到這裡的同學, 恭喜你正在悄悄的超越你們的專案小組長了~ 此時的程式碼在這裡

9150e4e5ly1fq0seoi54ng208c08cq4d

配置服務端渲染

我們已經能實現客戶端渲染的 React 專案, 走出了萬里長征的第一步. 接下來就是剩下的 9999 步了.

2019-07-12-11-08-39

首先, 在 src 目錄下建立 server.js 檔案作為服務端渲染的入口檔案. 其次, 編輯該檔案內容如下:

import Koa from 'koa';
import Router from 'koa-router';
import React from 'react';
import { renderToString } from 'react-dom/server';
import App from './components/App.jsx';

const app = new Koa();
const router = new Router();

const conf = {
  PORT: 9999,
};

const generateHtmlStr = reactDom => `
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>

    <div id="app">${reactDom}</div>
</body>
</html>
`;

router.get('*', (ctx) => {
  // 首先把 React 元件變成一個字串
  // eslint-disable-next-line
  const rNode = renderToString(<App />);
  // 然後替換 template 裡邊的內容
  const domString = generateHtmlStr(rNode);

  // 最後返回 html 字串
  ctx.body = domString;
});

app.use(router.routes(), router.allowedMethods());

app.listen(conf.PORT, () => {
  console.log(`The Server is listening on ${conf.PORT} now, enjoy`);
});
複製程式碼

程式碼和客戶端渲染的入口檔案 client.js 檔案大同小異

再次, 改寫專案根目錄下的 index.js 檔案, 匯入並執行一下剛剛建立的 server.js 檔案

require('./src/server')
複製程式碼

最後, 命令列執行 node index.js

2019-07-12-11-18-13

2019-07-12-11-17-18

仔細看下報錯資訊, 原來是 nodejs 不怎麼認識 es6 的模組化語法. 給我們的專案入口檔案新增個 babel. 修改專案根目錄下的indes.js 檔案如下:

require('@babel/register')({
  presets: ['@babel/env', '@babel/react'],
});
require('./src/server');
複製程式碼

再執行一下 node index.js

2019-07-12-11-32-27

看樣子要成功了~

2019-07-12-11-33-16

這個時候瀏覽器開啟 localhost:9999 如果你進入了澳門皇冠, 那肯定就值得信賴啦~

然後我們滑鼠右鍵 -> 檢視網頁原始碼 -> 驗貨

2019-07-12-12-01-47

雖然很簡單, 但是貨真價實, 正兒八經的服務端渲染. 此時程式碼在 這裡

後記

通過之前的步驟我們已經學習了使用 koa 實現最最基礎的服務端渲染專案(僅僅用到了一個 renderToString 這個 api), 在下篇文章中我們會一起學習在專案中加入 react-router redux 自定義 mata 等功能, 並實現其服務端渲染. 第一次接觸服務端渲染, 希望各路大佬能不吝賜教~

2019-07-12-11-51-56

相關文章