记录一次旧项目升级umi3到4的过程,希望踩过的坑可以给大家带来一点帮助。
项目背景:(只说一下重点)
react@16
antd@4(初始是antd3,升级到4的)
antd-pro@2(万年老版,已经不知道用在哪里)
umi@3.5(配套的 reatc-redux,dva)
react-router-dom@4(版本有点低)
项目本身是一套后台管理,小型系统,整体可控。
升级过程:
-
升级 reace@17
package.json 直接处理: "react": "^17.0.2” "react-dom": "^17.0.2",
好像没有任何不适,完美兼容,赞一下。(主要是第二步需要react@17)
-
引入
jotai
,用来代替dva
- 因为之前直接升级umi4,好像遇到了dva的问题
- 也因为旧项目,dva的封装, api.js --> model/project.js --> dispatch 的引用,还不能用 sync/await,让我不爽
- stroage数据不刷新,发布代码后,经常需要手动清空,原因不明
- 一个关键点:需要引入
React.Suspense
解决ajax请求白屏的问题。但也会带来过渡白屏的问题(尴尬),自己取舍吧。 - 最后留下一个空壳文件。 (该内容在升级完成后,移除了)
# modules/login.js
// 因为umi的问题,如果不保留,会导致加载dvajs报错,所以需要保留一下
export default {
namespace: 'login',
state: {},
effects: {
*tokenLogin({}, {}) {
return null;
},
},
};
- 最后才知道umi@4 max版也引入了
valtio
,貌似功能类似,不管了
- 升级 umi@4,参考的升级指南 https://umijs.org/docs/introduce/upgrade-to-umi-4
{
"devDependencies": {
+ "@umijs/max": "^4.0.0",
- "umi": "^3.0.0",
- "@umijs/preset-react": "^1.2.2"
}
}
- 修改 umi 的配置 config.js
import { defineConfig } from 'umi';
import routes from './router.config.js';
import defaultSettings from '../src/defaultSettings.js';
export default defineConfig({
plugins: [
'@umijs/plugins/dist/antd',
],
routes,
mfsu: {
strategy: 'normal',
},
antd: {},
hash: true,
history: { type: 'hash' },
outputPath: 'dist-build',
esbuildMinifyIIFE: true,
lessLoader: {
javascriptEnabled: true,
},
cssLoader: {
modules: {
getLocalIdent: (context, localIdentName, localName) => {
return localName;
},
},
},
});
- 升级 nodejs@16至 nodejs@18 ,我比较保守,慢慢升
- 关键点,需要安装
yarn add @umijs/plugins
yarn add @umijs/plugin-antd
,并在config中引入,否则antd相关的css貌似无法装载。 - esbuildMinifyIIFE 必须打开
-
outputPath: 'dist-build'
, 之前是outputPath: '/dist-build'
, 貌似判别方法变了 - 两个 cssLoader,不太明白,但GPT如是说,放上
- 还遇到自定义的 less 混合宏代码不生效,less代码重写后生效了。
- 在BasicLayout.menuList,渲染菜单树时卡了比较久,之前props.route,有所有路由表。现在没有了,只能自己用route.config.js去处理转换一下,因为比较深,递归也用上了。
- props中,不再包含 route / location {query} 需要自己往里填,所以自己包装了一个高阶函数(HOC),对所有组件包装一下,真累,不过同时把需要的全局字节数据也做了进去,确实也方便了许多。
// hoc.js
import { useAtom } from 'jotai';
import React from 'react';
import { useLocation, useSearchParams } from 'react-router-dom';
import allSampleTypesAtom, { allProductsAtom } from '@/models/atom.js';
import routesConfig from '../../config/router.config.js';
import { getRouter } from './utils.js';
// 因为升级umi4导致像 location.query不能直接获取,需要包装一下。顺便把需要的字典数据加进来
const withQueryParams = (WrappedComponent, dataLoads = {}) => {
return (props) => {
const location = useLocation();
const [searchParams] = useSearchParams();
// 将查询参数解析为对象格式
location.query = Object.fromEntries([...searchParams]);
// 获取路由
const route = getRouter(location.pathname, routesConfig);
// 附加数据
const appendData = {};
if (dataLoads.allProducts) {
const [allProducts] = useAtom(allProductsAtom);
appendData.allProducts = allProducts;
}
if (dataLoads.allSampleTypes) {
const [allSampleTypes] = useAtom(allSampleTypesAtom);
appendData.allSampleTypes = allSampleTypes;
}
return <WrappedComponent {...props} location={location} route={route} {...appendData} />;
};
};
export default withQueryParams;
使用时
import withQueryParams from '@/utils/hocs.js';
...
class SampleEdit extends PureComponent {
...
}
...
export default withQueryParams(SampleEdit); // SampleEdit;
- document.ejs 没用了,有点意外。加载外部的cdn,需要在config.js中增加配置项(不开心)
headScripts: [
{ src: 'https://rescdn.qqmail.com/node/ww/wwopenmng/js/sso/wwLogin-1.0.0.js' }
],
最后,yarn add prettier@latest -D
升级一下格式化工具
至此大面上的事情基本解决。基本耗时一周多的人力。后续慢慢体会 mako:{}, 倒底快没快
祝大家都升级顺利。
网友评论