Umi3升级到Umi4我踩了这些坑

最近升级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中没有暴露

原来的

  • 通过headScriptsindex.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中,使用useNavigateuseLocation 替换了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

总结

在项目技术栈升级实操过程中一定要有文档记录自己每一步的操作,当遇到问题时及时回溯操作的可行性。避免因为自己的操作,解决了一个问题却引入了其他问题,自己还不自知的情况。

相关推荐
2601_9583529014 小时前
A-59U 仅 37mm 却集成 USB + 双波束?
前端·回声消除·语音模块·降噪处理·降噪消回音
泯泷19 小时前
那段文字是谁删的?Yjs 14 正式版之前,一套删除归属方案的实现与边界
前端·javascript·算法
野槐1 天前
前端项目优化(有了我,会发生...)
前端
aa小小1 天前
【无标题】
前端
计算机魔术师1 天前
还在单线程跟 AI 聊天?Claude Code 并行多会话让你一个人干三个人的活
前端
志尊宝1 天前
Vue3 零基础每日笔记(038):亲手封装 useDebounceFn 与 useThrottleFn——高频事件的流量阀
前端·javascript·vue·html·vue3
JavaGuide1 天前
对标 MinIO!全新一代分布式文件系统正式发布
前端·后端
风骏时光牛马1 天前
AI驱动自动化业务工作流搭建实践
前端
码云之上1 天前
Skill 里的脚本终于能跑了,星悟接 CubeSandbox 的纪实
前端·人工智能·前端框架
IT_陈寒1 天前
Vue computed属性这个坑,我居然踩了三次才爬出来
前端·人工智能·后端