最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • react服务端渲染

    正文概述 掘金(明洁)   2021-02-22   560

    服务端渲染(ssr)和客户端渲染(csr)

    react服务端渲染

    • 服务端渲染:在服务端把你想要渲染的内容直接拼接成html字符串,然后返回给客户端渲染。
    • 客户端渲染:在浏览器端加载解析html完成之后,再去执行js代码,由js代码把你想要渲染的内容插入到页面中。

    服务端渲染和客户端渲染相比较,服务端渲染有利有弊,优点有如下:

    (1)加快了首屏渲染的速度
    (2)有利于seo优化,提高在搜索引擎中的排名。
    

    缺点有如下:

    (1)对开发者的要求更高,要了解服务端的知识。
    (2)增加了开发运维的成本,服务器资源开销比较大。
    

    所以,我们在开发中,到底要使用哪一种渲染方式,要根据具体的业务场景来订,不到万不得已,不要使用服务端渲染。

    服务端渲染基本流程

    • 初始化npm包,安装express或者koa(这里我用koa为例),搭建本地服务器。

    react服务端渲染

    然后编写服务器单独入口文件server/index.js,代码如下:

    import Koa from "koa";
    import fs from "fs";
    import path from "path";
    import React from "react";
    import { renderToString } from "react-dom/server";
    import Home from "../src/page/home/index.jsx";
    
    const app = new Koa();
    const rootPath = process.cwd();
    // 模板html的路径
    const templatePath = path.join(rootPath, "public/index.html");
    // 读取模板html内容
    const template = fs.readFileSync(templatePath).toString();
    
    app.use(async (ctx) => {
      const ssrContent = renderToString(<Home />);
      // 把模板html的内容替换成组件内容
      const html = template.replace("<!-- ssr slot -->", ssrContent);
      // 返回给浏览器
      ctx.body = html;
    });
    
    app.listen(3000);
    

    Home组件代码如下:

    import React from "react";
    
    const Home = () => { 
        const showInfo = () => alert('有用户点击');
        return <div className="home" onClick={showInfo}>Home</div>
    }
    
    export default Home;
    

    模板html内容,如下:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
    </head>
    <body>
        <!-- ssr slot -->
    </body>
    </html>
    

    现在基本服务器搭建完成。

    • 服务端webpack配置,对服务端的react代码进行打包。安装下图插件

    react服务端渲染

    在根目录下创建webpack.server.js文件,配置如下:

    const path = require("path");
    const nodeExternal = require("webpack-node-externals");
    module.exports = {
      mode: "development",
      target: "node",
      entry: path.resolve(__dirname, "./server/index.js"),
      output: {
        path: path.resolve(__dirname, "./server-build"), // 输出的路径
        filename: "server-bundle.js", // 打包后文件
      },
      externals: [nodeExternal()],
      module: {
        rules: [
          {
            test: /\.(js|jsx)$/,
            loader: "babel-loader",
            exclude: /node_modules/,
          },
        ],
      },
    };
    

    babel配置文件.babelrc如下:

    {
        "presets": [
            "@babel/preset-react",// react 转码规则
            "@babel/preset-env" // es2015规则
        ],
        "plugins":[
            "@babel/plugin-transform-runtime"
        ]
    } 
    

    package.json的script如下:

    react服务端渲染

    现在命令行运行npm run build:server完成之后,然后运行node ./server-build/server-build.js即可访问(localhost:3000)。但是,现在我们给组件加上点击事件,在浏览器端并不会做出响应,因为服务器端只负责前期试图呈现渲染的工作,并不会负责与用户的交互等操作,这些操作还是等交给浏览器的js来负责,所以现在我们需要打包编译客户端react代码并且引入(这个过程叫同构)。

    • 编写客户端react代码,新建client/index.js,如下:
    import React from "react";
    import ReactDom from "react-dom";
    import Home from "../src/page/home/index.jsx";
    
    ReactDom.hydrate(<Home />, document.getElementById("root"));
    
    • 客户端webpack配置,对客户端react代码进行打包,所安装插件和服务端一样。在根目录下新建webpack.client.js文件,配置如下:
    const path = require("path");
    module.exports = {
      mode: "development",
      entry: path.resolve(__dirname, "./client/index.js"), //指定入口文件,程序从这里开始编译,__dirname当前所在目录, ../表示上一级目录, ./同级目录
      output: {
        path: path.resolve(__dirname, "./client-build"), // 输出的路径
        filename: "client-bundle.js", // 打包后文件
      },
      module: {
        rules: [
          {
            test: /\.(js|jsx)$/,
            loader: "babel-loader",
            exclude: /node_modules/,
          },
        ],
      },
    };
    

    package.json的script如下:

    react服务端渲染

    运行npm run build:client打包完成之后,模板html引入客户端打包的代码并且服务器端配置静态资源访问即可。代码如下:

    // 模板html
    <!DOCTYPE html>
    <html lang="en">
      <head>
        <meta charset="UTF-8" />
        <meta http-equiv="X-UA-Compatible" content="IE=edge" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>Document</title>
      </head>
      <body>
        + <div id="root"><!-- ssr slot --></div>
        + <script src="/client-bundle.js"></script>
      </body>
    </html>
    
    ///////////////////////////////////////////////
    
    // 服务器端的代码
    import Koa from "koa";
    import fs from "fs";
    import KoaStatic from "koa-static";
    import path from "path";
    import React from "react";
    import { renderToString } from "react-dom/server";
    import Home from "../src/page/home/index.jsx";
    
    const app = new Koa();
    const rootPath = process.cwd();
    + // 静态文件路径
    + const staticPath1 = path.join(rootPath, "client-build");
    // 模板html的路径
    const templatePath = path.join(rootPath, "public/index.html");
    // 读取模板html内容
    const template = fs.readFileSync(templatePath).toString();
    + // 访问静态文件
    + app.use(KoaStatic(staticPath1));
    app.use(async (ctx) => {
      const ssrContent = renderToString(<Home />);
      // 把模板html的内容替换成组件内容
      const html = template.replace("<!-- ssr slot -->", ssrContent);
      console.log(html);
      // 返回给浏览器
      ctx.body = html;
    });
    
    app.listen(3000);
    
    

    现阶段如果服务端代码或者客户端代码有更改之后,需要我们手动去执行命令才能看到最新的结果。下面对webpack进行配置完成自动打包。首先安装nodemonnpm-run-all插件,然后配置package.json的script命令即可,代码如下:

    react服务端渲染

    现在我们只需要运行npm run dev即可,当我们的文件有更新时,刷新浏览器即可得到最新结果。

    后续会逐步加入react-router-dom和redux等,关注github仓库地址


    起源地下载网 » react服务端渲染

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元