umijs 服务端渲染(SSR) 指南

news2024/11/15 15:44:18

umijs 服务端渲染(SSR) 指南

Umi 是什么?

Umi,中文可发音为乌米,是可扩展的企业级前端应用框架。Umi 以路由为基础的,同时支持配置式路由和约定式路由,保证路由的功能完备,并以此进行功能扩展。然后配以生命周期完善的插件体系,覆盖从源码到构建产物的每个生命周期,支持各种功能扩展和业务需求。

Umi 是蚂蚁集团的底层前端框架,已直接或间接地服务了 3000+ 应用,包括 java、node、H5 无线、离线(Hybrid)应用、纯前端 assets 应用、CMS 应用等。他已经很好地服务了我们的内部用户,同时希望他也能服务好外部用户。

选择umijs v3版本

umijs v4版本已经发布,但是ssr功能还不完善,所以建议使用v3版本。

https://v3.umijs.org/zh-CN/docs/ssr

创建项目

mkdir umi-ssr-demo
cd umi-ssr-demo
npx @umijs/create-umi-app
npm i
npm run start

配置

    1. 配置 .umirc.js
import { defineConfig } from 'umi';

export default defineConfig({
  nodeModulesTransform: {
    type: 'none',
  },
  routes: [
    { path: '/', component: '@/pages/index' },
  ],
  fastRefresh: {},
  /** 开启ssr */
  ssr: {}
});

    1. 查看是否开启成功

20240606112924

如上图所示,直接返回了dom,不止一个根节点,这就算成功了

页面title、meta

每个页面都可以配置title和meta,通过配置<Helmet>组件即可

import React from 'react';
import { Helmet } from 'umi';

export default () => {
  return (
    <>
      {/* 可自定义需不需要编码 */}
      <Helmet>
        <title>Hello Umi Bar Title</title>
        <meta
          name="keywords"
          content="Hello Umi Bar Title"
        />
        <meta
          name="description"
          content="Hello Umi Bar Title"
        />
      </Helmet>
    </>
  );
};

获取接口数据

可以直接使用 umi-request 像spa应用一样获取接口数据,但是服务端渲染的,我们需要再服务器返回前就把数据获取好

每个页面有getInitialProps方法,在这个方法里可以获取数据,只有页面才有,组件是没有的

import React from 'react';

const Home = (props) => {
  const { data } = props;
  return (
    {/* <div>Hello World</div> */}
    <div>{data.title}</div>
  )
}

Home.getInitialProps = (async (ctx) => {
  return Promise.resolve({
    data: {
      title: 'Hello World',
    }
  })
})

当一个页面请求多个接口时,可以使用Promise.all()合并数据,能使请求速度变快,多个请求同时发出,而不是链式获取

import React from 'react';

const Home = (props) => {
  const { data } = props;
  return (
    {/* <div>Hello World</div> */}
    <div>{data.title}</div>
  )
}

Home.getInitialProps = (async (ctx) => {
  const [res1, res2] = await Promise.all([
    /** */
  ])
  return {
    res1,
    res2
  }
})

当数据量大了之后,会导致直接卡住,比如分页接口,调整了pageSize参数过大,可能导致页面卡死,可以将接口分片成多个请求,然后合并数据

export const useFiberRequest = async (fn, parames) => {
  const { page = 1, page_size = 10 } = parames?.pagination || {};
  const fiberSize = 10;
  const promiseList: any[] = [];

  for (let p = 1; p <= page_size / fiberSize; p++) {
    const pagination = {
      page: (page - 1) * (page_size / fiberSize) + p,
      page_size: fiberSize,
    };
    promiseList.push(
      fn({
        ...parames,
        pagination,
      }),
    );
  }

  const resList: any[] = await Promise.all(promiseList);

  const list = resList?.map((item) => item?.data?.list);
  const total = resList?.[0]?.data?.total || 0;
  return {
    data: {
      list: list?.flat(),
      total,
    },
  };
};

富文本

只有 div 标签 dangerouslySetInnerHTML 属性才能被 SSR 渲染,正常的写法应该是:

- <p dangerouslySetInnerHTML={{ __html: '<p>Hello</p>' }} />
+ <div dangerouslySetInnerHTML={{ __html: '<p>Hello</p>' }} />

与 dva 结合使用

已内置 dva,通过以下步骤使用:

    1. 配置.umirc.ts开启
export default {
  dva: {}
}

使用antd v5

由于antd v5是css in js的形式,所以样式是异步导入,导致ssr渲染时会先渲染出接口,然后闪一下,才加载出样式

我们可以把antd v5的样式提前加载,在ssr渲染时,先渲染出样式,然后再渲染出结构

  • 安装包
npm i -D @ant-design/static-style-extract ts-node cross-env
  • 生成antd v5 样式脚本
// src/scripts/genAntdCss.tsx
import { extractStyle } from '@ant-design/static-style-extract';
import fs from 'fs';

const outputPath = './public/css/antd.min.css';

// 1. default theme

const css = extractStyle();

// 2. With custom theme

// const css = extractStyle(withTheme);

fs.writeFileSync(outputPath, css);

console.log(`🎉 Antd CSS generated at ${outputPath}`);
  • 在package.json中添加脚本
{
  "scripts": {
    "predev": "ts-node --project ./tsconfig.node.json ./scripts/genAntdCss.tsx",
    "prebuild": "cross-env NODE_ENV=production ts-node --project ./tsconfig.node.json ./scripts/genAntdCss.tsx",
  }
}
  • 在app.tsx中引入
import '../public/css/antd.min.css';

部署

需要再起一个node服务,然后将ssr生成的dist目录作为静态资源目录

var Koa = require('koa'),
  logger = require('koa-logger'),
  json = require('koa-json'),
  views = require('koa-views'),
  onerror = require('koa-onerror');
const { extname } = require('path');

const app = new Koa();

// error handler
onerror(app);

let render;
app.use(async (ctx, next) => {
  const req = ctx.req;
  const res = ctx.res;
  const ext = extname(ctx.request.path);

  if (ext) {
    await next();
    return;
  }
  // 或者从 CDN 上下载到 server 端
  // const serverPath = await downloadServerBundle('http://cdn.com/bar/umi.server.js');
  if (!render) {
    render = require('./dist/umi.server');
  }
  res.setHeader('Content-Type', 'text/html');

  const context = {};
  const { html, error, rootContainer } = await render({
    // 有需要可带上 query
    path: req.url,
    context,

    // 可自定义 html 模板
    // htmlTemplate: defaultHtml,

    // 启用流式渲染
    // mode: 'stream',

    // html 片段静态标记(适用于静态站点生成)
    // staticMarkup: false,

    // 扩展 getInitialProps 在服务端渲染中的参数
    // getInitialPropsCtx: {},

    // manifest,正常情况下不需要
  });

  if (error) {
    console.log('----------------服务端报错-------------------', error);
    ctx.throw(500, error);
  }

  ctx.body = html;
});

// global middlewares
app.use(
  views('views', {
    root: __dirname + '/views',
    default: 'jade',
  }),
);
app.use(require('koa-bodyparser')());
app.use(json());
app.use(logger());

app.use(function* (next) {
  var start = new Date();
  yield next;
  var ms = new Date() - start;
  console.log('%s %s - %s', this.method, this.url, ms);
});

app.use(require('koa-static')(__dirname + '/dist'));

// error-handling
app.on('error', (err, ctx) => {
  console.error('server error', err, ctx);
});

module.exports = app;

运行node服务,将ssr生成的dist目录替换服务中的dist目录即可

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1793269.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

科普!终于把手机副卡给搞清楚了!

你知道什么是手机副卡吗&#xff1f; 你开通过手机副卡吗&#xff1f; 小小的脑袋&#xff0c;大大的疑问&#xff1f; 可能很多朋友对手机副卡这个词比较懵&#xff0c;那不要紧&#xff0c;接下来小编给大家介绍的这是关于手机副卡。 ​ 十个问题&#xff0c;带你搞清楚什…

专用于恢复iOS系统的数据恢复软件

一、简介 1、一款专门为苹果iOS设备设计的数据恢复软件&#xff0c;支持iPhone、iPad和iPod Touch等设备的数据恢复。这款软件能够恢复包括微信聊天记录、通讯录、短信、备忘录等多种类型的数据。用户可以通过设备扫描恢复、iTunes备份恢复和iCloud备份恢复三种模式来进行数据恢…

【MySQL数据库】MySQL 高可用搭建方案——MHA实战

MHA&#xff08;Master High Availability&#xff09; MHA实战 MHA&#xff08;Master High Availability&#xff09; 一、MHA简介二、MHA搭建准备要求&#xff1a;mha集群搭建&#xff0c;4台服务器&#xff0c;1主2从&#xff0c;1台mha2.1实验思路2.2实验准备 三、搭建MyS…

Python代码关系图生成,帮助快速熟悉一个项目

一、静态代码关系图 工具1、pyreverse pyreverse 是一个由 Logilab 开发的 Python 工具&#xff0c;它能够自动生成 UML (统一建模语言) 类图&#xff0c;这些类图基于 Python 源代码。pyreverse 可以分析 Python 代码&#xff0c;并从中提取出类、模块、函数、方法和它们之间…

如何通过Python SMTP配置示例发附件邮件?

Python SMTP配置的步骤&#xff1f;SMTP服务器的优缺点有哪些&#xff1f; 当我们需要发送包含附件的邮件时&#xff0c;自动化的解决方案显得尤为重要。Python提供了SMTP库&#xff0c;使我们能够轻松配置并发送带有附件的邮件。AokSend将通过一个示例来展示如何操作&#xf…

大坝监测新规范的改进与实施

近年来&#xff0c;为了进一步保障大坝的安全运行&#xff0c;相关部门对大坝监测规范进行了多项改进。本文将详细介绍这些改进措施及其重要性。 1、巡视检查的部位由原来的7个增加到8个&#xff0c;新增了对监测设施的巡查。这一改动确保了监测设施的正常运行&#xff0c;能够…

CR80通用清洁卡:证卡打印机、ATM机、POS机、读卡器等卡片设备清洁维护的好助手!

随着科技的进步&#xff0c;ATM机、POS终端、门禁系统、证卡打印机、读卡器等卡片设备在我们的日常生活中扮演着越来越重要的角色&#xff0c;些设备在长时间使用和环境因素的影响下&#xff0c;容易积聚油脂、灰尘和其他污染物&#xff0c;从而对其性能和功能产生负面影响。 深…

广东智慧物流2024年端午节放假安排

广东智慧物流2024年端午节放假安排

C# 反射类Assembly 程序集(Assembly)用法

常见的两种程序集&#xff1a; 可执行文件&#xff08;.exe文件&#xff09;和 类库文件&#xff08;.dll文件&#xff09;。 在VS开发环境中&#xff0c;一个解决方案可以包含多个项目&#xff0c;而每个项目就是一个程序集。 他们之间是一种从属关系&#xff0c;也就是说&…

【YOLOv10改进[CONV]】2024年的DynamicConv助力YOLOv10目标检测效果 + 含全部代码和详细修改方式 + 手撕结构图 + 全网首发

本文将使用2024的DynamicConv助力YOLOv10目标检测效果的实践,文中含全部代码、详细修改方式以及手撕结构图。助您轻松理解改进的方法。 改进前和改进后参数量对比: 目录 一 DynamicConv

PyTorch 相关知识介绍

一、PyTorch和TensorFlow 1、PyTorch PyTorch是由Facebook开发的开源深度学习框架&#xff0c;它在动态图和易用性方面表现出色。它以Python为基础&#xff0c;并提供了丰富的工具和接口&#xff0c;使得构建和训练神经网络变得简单快捷。 发展历史和背景 PyTorch 是由 Fac…

EDA数据跨网交换解决方案,一文了解

EDA数据通常与电子设计自动化相关&#xff0c;这是一种利用计算机辅助设计&#xff08;CAD&#xff09;软件来完成超大规模集成电路&#xff08;VLSI&#xff09;芯片的功能设计、综合、验证、物理设计等流程的技术。以下是一些会涉及到EDA数据的行业&#xff1a; 集成电路设计…

生命在于学习——Python人工智能原理(3.2)

三、深度学习 &#xff08;二&#xff09;人工神经网络 人工神经网络是模仿人类大脑神经系统工作原理所创建的数学模型&#xff0c;有并行的分布处理能力、高容错性和自我学习等特征。 1、感知器 感知器由Frank Roseblatt于1957年提出&#xff0c;是一种广泛使用的线性分类…

桌面型激光雕刻机的发展前景及TMC应用优势

一、行业现状 近两年来&#xff0c;激光雕刻行业正处于快速发展阶段。随着人们生活水平的提高&#xff0c;对个性化、定制化产品的需求日益增加&#xff0c;激光雕刻以其独特的创意和精美的效果&#xff0c;满足了消费者对个性化产品的追求。同时&#xff0c;随着科技的不断进…

svg完成鼠标样式并使用

本次分享的是通过svg标签实现的鼠标样式&#xff0c;并在页面中进行使用的整个过程&#xff0c;最后还会分享快速制作svg的简单方式。 如有改进的方法或者发现错误也可以在评论区留言啊。 一、鼠标的svg样式 1.小飞机型 <svg width"32" height"32" xml…

[行业原型] 汽车供应链多地分销一站式云端解决方案

互联网改变了企业经营模式、竞争环境&#xff0c;同时还在改变企业的交易方式&#xff0c;影响着企业间的协作。 全球化电子商务环境下&#xff0c;传统的供应链管理模式不能适应新环境下供应链管理要求&#xff0c;新的供应链管理模式—eSCM。 eSCM是将分销管理、客户资源管理…

Xilinx RFSOC 47DR 8收8发 信号处理板卡

系统资源如图所示&#xff1a;  FPGA采用XCZU47DR 1156芯片&#xff0c;PS端搭载一组64Bit DDR4,容量为4GB,最高支持速率&#xff1a;2400MT/s;  PS端挂载两片QSPI X4 FLASH&#xff1b;  PS支持一路NVME存储&#xff1b;  PS端挂载SD接口&#xff0c;用于存储程序&…

Django ORM深度游:探索多对一、一对一与多对多数据关系的奥秘与实践

系列文章目录 Django入门全攻略&#xff1a;从零搭建你的第一个Web项目Django ORM入门指南&#xff1a;从概念到实践&#xff0c;掌握模型创建、迁移与视图操作Django ORM实战&#xff1a;模型字段与元选项配置&#xff0c;以及链式过滤与QF查询详解Django ORM深度游&#xff…

Mac 苹果电脑下载安装《植物大战僵尸杂交版2.0.88》详细指南教程(含已损坏打不开等问题解决)

最近植物大战僵尸杂交版可是非常的火爆&#xff0c;各大主播都在玩&#xff0c;可是该游戏作者只发布了win版本&#xff0c;我只有一台 Macbook 一直都很想玩&#xff0c;经过一番折腾终于在Mac上成功安装运行了该游戏&#xff0c;并整理好了&#xff0c;大家想要在 Mac 上安装…

win11通过网线分享网络到Ubuntu工控机

1.条件&#xff1a;一个能无线联网的win11&#xff0c;一根网线&#xff0c;一台Ubuntu工控机&#xff0c;并且使用网线连接两者 2.在win11电脑上 2.1 打开控制面板的网络和Internet 2.2 进入网络和共享中心&#xff0c;在左侧进入 更改适配器设置 2.3 在WLAN上右键&#xff0…