umi3.5升4.0,react17升18踩坑之路

1、背景

由于部分页面有性能问题,前端同学也在研究提升性能方面的方法,除了一些常用方法之外,还了解到react18有部分API可以提升性能,所以想把项目中用到的React版本由17升到18。

经过调研,如果直接把项目React17改成18版本,项目编译时会报错,报错信息如下
在这里插入图片描述

原因是umi3.5.x版本的render-react包依赖的react不支持18,如图
在这里插入图片描述
在这里插入图片描述
所以如果要升react18的话必须把umi升到4.x版本。

2、开启umi升级踩坑之路

2.1、修改配置

1) 首先删除 package-lock.json, pnpm-lock.yaml,node_modules,.umi文件夹

2)package.json 需要移除umijs等相关插件,如@umijs/plugin-esbuild @umijs/route-utils @umijs/preset-react umi umi-plugin-keep-alive

3)package.json需要添加 “react”: “^18.2.0”,“react-dom”: “^18.2.0”,“@types/react”: “^18.2.0”,“@types/react-dom”: “^18.2.0”, “@umijs/max”: “4.0.40”

4)tsconfig.json配置 “compilerOptions”:{ “types”: [“node”,“react”] }

5)修改package.json中script的启动命令,因为@umijs/max将一些项目前置操作放到了 setup 命令中,如 umi@3 中的 umi g tmp 等命令,需要使用 max setup 替换
在这里插入图片描述
6)修改.umirc.ts
将mfsu 和webpack5配置去掉,因为umi max默认开启了mfsu和webpack5
在这里插入图片描述

去掉nodeModulesTransform 和 dynamicImport,增加 initialState: {}, model: {}, hash: true, historyWithQuery:{}, fastRefresh: true,antd: {},如果用到了keepalive插件需要添加 plugins: [‘umi-plugin-keep-alive’], 当然不要忘记安装这个插件了哦,执行pnpm add umi-plugin-keep-alive --save-dev
在这里插入图片描述

  • hash 官方竟然默认是false, 开启后会让build之后的产物包含hash后缀,如umi.df723s.js,
    umi.8sd8fw.css,通常用于增量发布和避免浏览器加载缓存,所以别忘了设置为true
  • antd: {} 必须设置,不然打包生成样式会缺少antd样式
  • historyWithQuery 官方竟然默认是false, 导致history.push({ pathname: '/', query: { id } }) 跳转页面不会携带id,所以我们一定要设置上去

2.2 layout层修改

Umi 4 中将 react-router@5 升级到 react-router@6,所以路由相关的一些 api 存在着使用上的差异。 props 默认为空对象,以下属性都不能直接从 props 中取出
在这里插入图片描述
导致layouts 中的文件,取props.children获取为空,需要用umi的Outlet组件替换, 如图
在这里插入图片描述

2.3 wrappers层修改

同理,wrappers层用props.children取值渲染的地方也要改成umi max的Outlet

  • view-error.tsx
    在这里插入图片描述
  • view-auth.tsx (顺便替换了props.location)
    在这里插入图片描述
  • system-auth.tsx
    使用了 React.cloneElement 方式渲染的路由组件改造
    在这里插入图片描述
  • keepalive.tsx
    在这里插入图片描述
  • auth.tsx
    在这里插入图片描述
  • auth-button.tsx
    在这里插入图片描述

2.4 修改从wrappers里传过来的属性获取方式

由于把wrappers层的props.children改成了Outlet,那么从props里取systemConfig,dictConfig,productionModalConfig等属性,需改成如下图方式获取
在这里插入图片描述

这里代码涉及处挺多的,别改漏了

2.5 修改history

1)由于从props里获取不到history了,需要改成从umi里直接引用,import { history } from 'umi'

2)history.push的Api也有改变,如果传了state,需修改传参,如下图
在这里插入图片描述
3)history.goBack() 需改成 history.back()history.go(-1)

  1. history.listen的获取值方式改变, 如下图

2.6 修改location取值方式

1)从props.location 需改成 import { useLocation } from 'umi'; let location = useLocation();

2)从props.location.query里取值的方式需要改成从history.location.query 或者 useLocation().search里获取,再用query-string解析获取
在这里插入图片描述

2.7 useActivate, useUnactivate导入方式由umi改成react-activation

在这里插入图片描述

2.8 使用了useModel的页面,再使用KeepAlive,都会报错:Uncaught TypeError: Cannot read properties of null (reading 'dispatcher')

在.umirc.ts里配置了model: {}; initialState:{} 就可以使用useModel了,但是与keepalive同时使用会报错,解决步骤如下:

1)需要安装插件 pnpm add umi-plugin-keep-alive --save;

2)需要在.umirc.ts文件中手动配置开启插件,plugins: [‘umi-plugin-keep-alive’]

3)src/app.ts中添加如下配置
在这里插入图片描述

2.9 react报错ReactDOM.render is no longer supported in React 18

在18.0版本中,React 18 不再支持 ReactDOM.render,需使用createRoot代替
在这里插入图片描述

2.10 pnpm build 报错 export ‘IFormilySchema’ (reexported as ‘IFormilySchema’) was not found in ‘@designable/formily-transformer’ (possible exports: transformToSchema, transformToTreeNode)

意思是重复导出的变量没有找到,写法如下
在这里插入图片描述
可是在 @designable/formily-transformer这个包里明明有导出这个类型定义呀,如图
在这里插入图片描述
后来经过研究,需要在导出的非变量前面加上type才可以,写法如下
在这里插入图片描述
这样再重新build就不会报错了

tips: 本次改动量比较多,涉及到的文件量比较大,不确定还有没有地方遗漏,要上线的话还需要做个上线的方案

  • 22
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值