首页
/ Material UI v4 到 v5 迁移实战:ThemeProvider 前置准备、包名重构与 preset-safe codemod 全流程

Material UI v4 到 v5 迁移实战:ThemeProvider 前置准备、包名重构与 preset-safe codemod 全流程

2026-09-06 15:52:39作者:庞队千Virginia

本文基于 Material UI 仓库官方迁移文档 migration-v4.md,完整覆盖从 v4 升级到 v5 的每一步前置准备:浏览器与 Node 目标版本变化、React/TypeScript 最低版本要求、ThemeProvider 强制前置、@material-ui/*@mui/* 的包名重构,以及 preset-safevariant-proplink-underline-hover 三个 codemod 的适用条件与限制。读完并照做后,你可以按“小步提交、逐步验证”的节奏把应用平稳升到 v5,并能用仓库内 codemod 源码验证每一类转换的底层行为。

迁移系列文档导航

这是一篇多部分系列文档的第一篇,完整迁移路线如下:

  1. 开始迁移(本文)
  2. 破坏性变更(一):样式与主题
  3. 破坏性变更(二):组件
  4. 从 JSS 迁移
  5. 故障排查

官方强烈建议优先运行仓库提供的 codemods,它们能自动处理 v5 引入的大部分破坏性变更,本文“运行 codemods”一节详细说明。

为什么应该迁移到 v5

v5 相对 v4 包含大量 bug 修复与改进,其中最重要的变化是样式引擎从 JSS 换成了 Emotion

  • 动态样式的性能有显著提升,开发体验更好;
  • v5 是唯一完整支持 React 18 的版本,想用 React 18 的新特性就必须迁移;
  • v5 发布详情可参考仓库内的发布博客 mui-core-v5.md

两个关键的过渡性事实:

  1. JSS 可以继续用:迁移到 v5 后,你仍可继续使用 makeStyleswithStyles 等 JSS 工具给组件添加覆盖样式(通过已废弃但仍可用的 @mui/styles 包)。官方建议是:先完成其余 v5 升级步骤,再按 从 JSS 迁移 渐进式切换到新样式引擎。
  2. 小步提交:迁移过程中每完成一步就提交一次,出问题先查 故障排查 文档。

支持的浏览器与 Node 版本

v5 调整了默认构建产物(default bundle)的目标版本,由 browserslist 查询语句锁定:

"> 0.5%, last 2 versions, Firefox ESR, not dead, not IE 11, maintained node versions"

v5.0.0 发布时快照的最小支持版本(相对 v4 的变化):

运行环境 v5 最低版本 v4 最低版本
Node 12 8
Chrome 90 49
Edge 91 14
Firefox 78 52
Safari 14 (macOS) / 12.5 (iOS) 10

Material UI v5 不再支持 IE 11。如果必须支持 IE 11,官方提供了 legacy bundle 构建方式作为替代方案(见仓库内“minimizing bundle size”指南)。

仓库内的 .browserslistrc 佐证

仓库根目录的 .browserslistrc 就是这份目标声明的落地文件:[stable] 段是随主版本发布时固定的浏览器清单快照,[node]/[coverage]/[development]/[test] 段则分别固定 Node 版本(当前快照为 node 14.0)。从当前文件内容看,stable 快照已演进到 Chrome/Edge 117+、Firefox 121+、Safari 17+,说明该目标基线随版本持续抬高——上面表格是 v5.0.0 发布时的快照,你升级时应以你所发布版本对应的 .browserslistrc 为准。文件头部注释也明确说明:更新版本后可能需要同步仓库中所有标注 #stable-snapshot 的引用(本文原文中的版本表格即由该标记驱动生成)。

更新 React 与 TypeScript 版本

更新 React

React 最低支持版本从 16.8.0 提升到 17.0.0。如果你的 React 低于 17,先把依赖升到 Material UI ^4.11.2 + React ^17.0.0

npm install @material-ui/core@^4.11.2 react@^17.0.0
yarn upgrade @material-ui/core@^4.11.2 react@^17.0.0

更新 TypeScript

TypeScript 最低支持版本从 3.2 提升到 3.5。官方与 DefinitelyTyped(npm 上 @types 命名空间的类型包)发布的类型对齐,且承诺不会在 minor 版本中提高最低支持版本;一般建议不要使用低于 DefinitelyTyped 最低支持版本的 TypeScript。

如果项目中存在以下包,需要一并更新:

  • react-scripts
  • @types/react
  • @types/react-dom

检查点:确认应用无错误运行后提交代码,再进入下一步。

设置 ThemeProvider(强制前置条件)

在升级到 v5 之前,无论是否使用默认主题,都必须确保 ThemeProvider 已定义在应用根部和测试中,并且 useStyles 的调用位置晚于/位于 ThemeProvider 内部。这个要求对后续 JSS 过渡期同样有效——@mui/styles 包依赖 ThemeProvider 提供主题上下文。

应用根部结构示例(直接继承自官方文档):

import { ThemeProvider, createMuiTheme, makeStyles } from '@material-ui/core/styles';

const theme = createMuiTheme();

const useStyles = makeStyles((theme) => {
  root: {
    // some CSS that accesses the theme
  }
});

function App() {
  const classes = useStyles(); // ❌ If you have this, consider moving it
  // inside of a component wrapped with <ThemeProvider />
  return <ThemeProvider theme={theme}>{children}</ThemeProvider>;
}

检查点:确认应用无错误运行并提交后,再进入下一步。

更新 Material UI 相关包

安装 v5 主包与过渡包

npm install @mui/material @mui/styles
yarn add @mui/material @mui/styles

若你使用了 @material-ui/lab@material-ui/icons,需要安装对应新包:

npm install @mui/lab
npm install @mui/icons-material
yarn add @mui/lab @mui/icons-material

日期时间选择器已迁往 MUI X

@material-ui/date-pickers 以及 @mui/lab 中的 pickers 组件已移入 MUI X 产品线,如在使用需迁移到 @mui/x-date-pickers(该仓库内的迁移文档为 pickers-migration.md)。

Emotion 依赖

v5 默认样式引擎是 Emotion,需补充 peer 依赖:

npm install @emotion/react @emotion/styled
yarn add @emotion/react @emotion/styled

styled-components 替代方案(可选):若希望用 styled-components 而非 Emotion,可改用适配包 @mui/styled-engine-sc。注意:若应用使用 SSR,styled-components 的 Babel 插件存在已知 bug(官方 issue #29742),会导致 @mui/styled-engine-sc 无法正常工作——官方强烈建议直接用默认 Emotion 方案。仓库中两套引擎适配层的源码分别位于 mui-styled-engine(Emotion)与 mui-styled-engine-sc(styled-components),可以对照其实现理解适配边界。

检查点:确认应用无错误运行并提交后,再进入下一步。

替换所有 import:包名映射总表

v5 随品牌重塑将所有 @material-ui/* 包改名为 @mui/*,映射关系如下:

@material-ui/core -> @mui/material
@material-ui/unstyled -> @mui/base
@material-ui/icons -> @mui/icons-material
@material-ui/styles -> @mui/styles
@material-ui/system -> @mui/system
@material-ui/lab -> @mui/lab
@material-ui/types -> @mui/types
@material-ui/styled-engine -> @mui/styled-engine
@material-ui/styled-engine-sc -> @mui/styled-engine-sc
@material-ui/private-theming -> @mui/private-theming
@material-ui/codemod -> @mui/codemod
@material-ui/docs -> @mui/internal-core-docs
@material-ui/envinfo -> @mui/envinfo

这份映射在本仓库的 monorepo 目录结构中可以得到印证:packages/ 下已按新品牌组织,如 mui-materialmui-labmui-icons-materialmui-systemmui-typesmui-utilsmui-private-themingmui-envinfomui-codemod,文档包则对应 core-docs

移除旧包

安装完所有新包且确认应用正常运行后,可以移除旧的 @material-ui/* 包:

npm uninstall @material-ui/*
# 或
yarn remove @material-ui/*

preset-safe codemod(下一节)会自动完成 import 替换与包名切换,通常无需手动执行。

修正 CSS 特异性(可选)

如果你通过导入 CSS 文件的方式给组件加样式,v5 中需要提高选择器特异性才能命中目标部件。示例(继承自官方文档):

import './style.css';
import Chip from '@mui/material/Chip';

const ChipWithGreenIcon = () => (
  <Chip
    classes={{ deleteIcon: 'green' }}
    label="delete icon is green"
    onDelete={() => {}}
  />
);

正确的做法是借助组件根的 MuiChip-root 类提升特异性:

.MuiChip-root .green {
  color: green;
}

而下面的写法不会把样式应用到删除图标上:

.green {
  color: green;
}

原因在于:Emotion 生成的类(如 MuiChip-root)与 classes 传入的类名挂在同一 DOM 层级的父子关系上,单类选择器 .green 的特异性与组件内置样式打平时可能被覆盖,加上 .MuiChip-root 前缀后形成后代组合选择器,才能稳定胜出。

运行 codemods

以下 codemod 会自动完成大部分 v5 破坏性变更的代码调整。每运行完一个 codemod,都要确认应用仍能无错误运行并提交代码。

preset-safe(主力迁移工具)

包含迁移所需的大多数转换器,每个文件夹只应运行一次

npx @mui/codemod@latest v5.0.0/preset-safe <path>

从源码看,preset-safe.js 是一个顺序执行约 50 个 jscodeshift 转换器的组合函数,覆盖主题迁移(theme-spacingtheme-breakpointstheme-augmentcreate-theme)、组件 prop 变更(icon-button-sizedialog-propsmodal-propstable-props)、样式迁移(material-ui-stylesemotion-prepend-cachestyled-engine-provider)、包名替换(mui-replace)与最优导入路径(optimal-imports)等类别,官方 README 中给出了每个子转换器的独立运行命令与 diff 示例,行为则由 preset-safe.test.js 等测试用例固化。

codemod CLI 本身还提供更细的控制选项(来自 mui-codemod README):

npx @mui/codemod@latest <codemod> <paths...>
# 常用选项:
# --dry          干跑,不修改任何文件
# --parser       jscodeshift 解析器(默认 'tsx',可选 flow 等)
# --print        把转换结果打印到 stdout
# --packageName  使用了自定义再导出包名时指定,例如 --packageName="@org/ui"
# --jscodeshift  透传 jscodeshift 参数,如 "--run-in-band --verbose=2"

建议先加 --dry 预览改动范围,再正式执行。

variant-prop(TextField / FormControl / Select 变体)

该 codemod 为未定义 variant<TextField/><FormControl/><Select/> 补上 variant="standard"——因为默认 variant 从 v4 的 "standard" 变成了 v5 的 "outlined"

禁止使用的场景:如果你已在主题中把默认 variant 设为 outlined,就不要运行它,否则会造成重复/冲突:

// ❌ 如果你有这样的主题配置,不要运行此 codemod
// 这些 defaultProps 后续可以移除,因为 v5 中 outlined 已是默认值
createMuiTheme({
  components: {
    MuiTextField: {
      defaultProps: {
        variant: 'outlined',
      },
    },
  },
});

若你确实希望保留 variant="standard",则运行该 codemod 或在主题中配置对应 defaultProps:

npx @mui/codemod@latest v5.0.0/variant-prop <path>

link-underline-hover(Link 下划线)

该 codemod 为未定义 underline<Link /> 补上 underline="hover"——默认值从 v4 的 "hover" 变成了 v5 的 "always"

禁止使用的场景:若主题中已默认 underline: "always",不要运行:

// ❌ 如果你有这样的主题配置,不要运行此 codemod
// 该 defaultProps 后续可移除,因为 v5 中 always 已是默认值
createMuiTheme({
  components: {
    MuiLink: {
      defaultProps: {
        underline: 'always',
      },
    },
  },
});

若希望保留 underline="hover",运行该 codemod 或配置对应主题 defaultProps:

npx @mui/codemod@latest v5.0.0/link-underline-hover <path>

处理剩余破坏性变更

codemods 覆盖了大部分变更,但仍有一类需要手工处理。无论是否使用了 codemods,接下来都应按顺序阅读并完成两篇破坏性变更文档:

  1. 样式与主题的破坏性变更
  2. 组件的破坏性变更

完成后按 从 JSS 迁移 切换样式引擎;遇到异常时优先查阅 故障排查

另外,如果你使用 Next.js 且不确定如何配置 SSR 让 Emotion 与 JSS 共存,本仓库内置了可直接参考的迁移示例工程 examples/material-ui-nextjs-ts-v4-v5-migration/,其中 srctypes 目录展示了双引擎共存下的服务端渲染配置方式,可作为升级过程中的对照模板。

登录后查看全文
热门项目推荐
相关项目推荐

项目优选

收起
kernelkernel
deepin linux kernel
C
33
18
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.14 K
2.75 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
857
1.35 K
docsdocs
暂无描述
Markdown
898
5.82 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
531
596
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
921
1.84 K
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.8 K
1.02 K
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.36 K
1.46 K
cann-learning-hubcann-learning-hub
CANN 学习中心仓,支持在线互动运行、边学边练,提供教程、示例与优化方案,一站式助力昇腾开发者快速上手。
Jupyter Notebook
1.02 K
519
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
548
391