最近升级Umi,踩了一些坑,总结记录了一下,发出来分享一下,大概四五千字,升级遇到问题的小伙伴可以来查阅一下。
按照官网更改依赖
项目的 package.json
需要升级 Umi,并替换掉对应的 Umi 插件。
如果 umi@3
中是使用 umi
+ @umijs/preset-react
的组合进行开发的,那可以直接使用新版的 max
直接升级。
diff
{
"devDependencies": {
+ "@umijs/max": "^4.0.0",
- "umi": "^3.0.0",
- "@umijs/preset-react": "^1.2.2"
}
}
删除 node_module
,执行下 npm install
重装依赖。
报错了
这里报错 没有umi
,把postinstall
删掉试一下,install成功了。
把postinstall钩子删掉了
更改启动命令
diff
{
"scripts": {
- "build": "umi build",
+ "build": "max build",
- "postinstall": "umi g tmp",
+ "postinstall": "max setup",
- "start": "umi dev",
+ "start": "max dev",
}
}
恢复postinstall钩子,用max setup替换umi g tmp
让后npm run dev
启动一下,又报错,runtimePublicPath
配置的值无效,先不启动了,按照官网改.umirc.ts
css
fatal - AssertionError [ERR_ASSERTION]: Invalid config values: runtimePublicPath
Invalid value for runtimePublicPath:
[
{
"code": "invalid_type",
"expected": "object",
"received": "boolean",
"path": [],
"message": "Expected object, received boolean"
}
]
修改配置文件
- 更改
umi
为@umijs/max
diff
- import { defineConfig } from 'umi';
+ import { defineConfig } from '@umijs/max';
mock
属性
diff
- mock: isDev ? {} : false,
+ mock: {},
umi4
默认开启webpack5
,删除webpack
配置
diff
- webpack5: {}
- 更改
runtimePublicPath
diff
- runtimePublicPath: true,
+ runtimePublicPath: {},
- 删除
title
,默认为null
,无需设置false
diff
- title: false,
- 删除
nodeModulesTransform
diff
- nodeModulesTransform: {
- type: 'none',
- exclude: [],
- },
- 删除
locale
,不知道是干嘛的?
diff
- locale: { antd: true },
- 删除
dynamicImport
,Umi 4 默认 按页分包 ,从而在页面切换时存在加载过程,通过该文件来配置加载动画。在目录结构下添加loading.tsx
diff
- dynamicImport: {
- loading: '@/components/Loading',
- },
- 在
.umirc.ts
中添加historyWithQuery
字段
diff
// .umirc.ts
{
+ historyWithQuery: {},
}
现在启动一下npm run dev
,又报错了!!!!!
vbnet
error - [MFSU][eager] worker got Error Error: Cannot find module 'umi/dist/service/service'
Require stack:
代码层面更改
将页面中所有umi
的导入改为@umijs/max
diff
- import { } from 'umi';
+ import { } from '@umijs/max';
在npm run dev 启动一下,依然保持,与上面保持相同,找不到模块
umi/dist/service/service
然后升级了node到v20
删除node_modules和package-lock.json文件
重新
npm install
再次
npm run dev
它又报错了,啊啊啊!!!
vbnet
ValidationError: Invalid options object. CSS Loader has been initialized using an options object that does not match the API schema.
- options has an unknown property 'localsConvention'. These properties are valid:
object { url?, import?, modules?, sourceMap?, importLoaders?, esModule?, exportType? }
删掉css-loader
配置
diff
- cssLoader: {
- localsConvention: 'asIs',
- },
重新
npm run dev
报错
index.html
没有暴露window.publicPath
在index.html要暴露
window.publicPath
,但是升级后的index.html中没有暴露
原来的
- 通过
headScripts
向index.html
注入全局变量脚本
diff
// .umirc.ts
{
+ headScripts: [
+ 'window.routerBase = "abc/"',
+ 'window.publicPath = window.resourceBaseUrl || "abc/";',
+ ]
}
注入后:
再次执行
npm run dev
又报错,但是有预感快成功了
因为上面
window.publicPath
配置的一个写死的字符串改为
bathPath
变量再次启动
又又又报错
改成了这样
再次执行
npm run dev
又报了其他错误
getInitialState
注册失败
vbnet
Unhandled Rejection (Error): register failed, invalid key getInitialState from plugin /Users/mac/Desktop/xxxxx/src/app.ts.
提示我
getInitialState
注册不成功,真坑
umi4
需要,在.umirc.ts
中添加配置
diff
// .umirc.ts
{
+ initialState: {},
+ model: {}, // 使用useModel需要这个配置
}
再次
npm run dev
跑起来了!!
路由好像失败了!!!
只展示出来一个layout,antd的主题样式自定义也没了
先解决只展示layout的问题
按照umi/max
新规范,需要使用<Outlet />
替换children
diff
import React from 'react';
+ import { Outlet } from 'umi';
export default function Layout(props) {
return (
<div>
- { props.children }
+ <Outlet />
</div>
);
}
修改完后项目展示部分正常了
使用useHistory
的部分又报错了!!!!
因为Umi4将
React-Router@5
升级到了React-Router@6
在
React-Router@6
中,使用useNavigate
和useLocation
替换了useHistory
将项目中使用
useHistory
替换为useNavigate
再次执行
npm run dev
项目启动,报错没了
_layout.tsx
文件失效了,气人 !!!
经查询,把原来的_layout.tsx
文件放到与所在目录同级,并改名为与目录名相同,如下:
原来的:
lua
|--parent
| |--index.tsx
| |--_layout.tsx
更新后:
css
|--parent
| |--index.tsx
|--parent.tsx # 原来的_layout.tsx
重新
npm run dev
正常了
动态路由出现错误
Umi4约定式路由使用
$id.tsx
,不在支持[id].tsx
总结
在项目技术栈升级实操过程中一定要有文档记录自己每一步的操作,当遇到问题时及时回溯操作的可行性。避免因为自己的操作,解决了一个问题却引入了其他问题,自己还不自知的情况。