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

总结

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

相关推荐
everyStudy32 分钟前
前端五种排序
前端·算法·排序算法
甜兒.2 小时前
鸿蒙小技巧
前端·华为·typescript·harmonyos
Jiaberrr5 小时前
前端实战:使用JS和Canvas实现运算图形验证码(uniapp、微信小程序同样可用)
前端·javascript·vue.js·微信小程序·uni-app
everyStudy5 小时前
JS中判断字符串中是否包含指定字符
开发语言·前端·javascript
城南云小白5 小时前
web基础+http协议+httpd详细配置
前端·网络协议·http
前端小趴菜、5 小时前
Web Worker 简单使用
前端
web_learning_3216 小时前
信息收集常用指令
前端·搜索引擎
tabzzz6 小时前
Webpack 概念速通:从入门到掌握构建工具的精髓
前端·webpack
200不是二百6 小时前
Vuex详解
前端·javascript·vue.js
滔滔不绝tao6 小时前
自动化测试常用函数
前端·css·html5