
Material UI v5 升级到 v6React 19 铺垫、破坏性变更与 Codemod 迁移实战【免费下载链接】material-uiMaterial UI: Comprehensive React component library that implements Googles Material Design. Free forever.项目地址: https://gitcode.com/GitHub_Trending/ma/material-ui本篇指南基于 Material UI 官方迁移文档 upgrade-to-v6.md 编写系统讲解从 Material UI v5 升级到 v6 的动机、环境基线变化、全部破坏性变更、对测试与 TypeScript 类型的影响以及配套的mui/codemod自动化迁移工具。读完本文后你可以按步骤完成一次低风险的 v5 → v6 升级正确设置浏览器与 Node.js 支持基线、处理react-is版本冲突、运行官方 codemod 批量改写Grid2、ListItem、styled等用法并理解每一项变更在仓库源码中的实现依据。为什么要升级到 v6Pigment CSS为 React Server Components 铺路v6 最大的战略变化是引入了Pigment CSS——一个零运行时zero-runtime的 CSS-in-JS 样式引擎定位为替代 Emotion 与 styled-components 的、面向 React 19 及以后版本更具前瞻性的样式方案。其核心差异在于样式在构建时build time提取而非运行时注入避免了客户端的样式重算由此解锁了 React Server ComponentRSC的兼容性同时显著减小 Material UI 应用的 bundle 体积。在 v6 中 Pigment CSS 是可选opt-in的并非默认启用。官方判断后续主版本大概率会将其设为默认样式方案因此鼓励开发者在升级到 v6 之后尽早试用 Pigment CSS具体流程参见 Pigment CSS 迁移指南。仓库中已存在对应的实验性封装如 packages/mui-material-pigment-css/ 目录印证了这一集成方向。体验改进Quality-of-life improvementsv6 还带来了几项日常开发体验改进ThemeProvider现在支持全部CssVarsProvider的能力CSS 主题变量支持容器查询container queries新增主题工具theme.applyStyles()用于按颜色模式light/dark附加样式下文详述。版本号同步升级的配套包如果项目同时使用了以下包可以将版本一并改为6.0.0mui/icons-materialmui/systemmui/labmui/material-nextjsmui/styled-engine-scmui/utils对应仓库目录均可在 packages/ 下找到例如 packages/mui-system/、packages/mui-lab/、packages/mui-styled-engine-sc/ 等。注意MUI X 系列包不遵循 Material UI 的版本策略。以下包在升级过程中应保持版本不变mui/x-data-grid、mui/x-data-grid-pro、mui/x-data-grid-premiummui/x-date-pickers、mui/x-date-pickers-promui/x-chartsmui/x-tree-view、mui/x-tree-view-pro支持的浏览器与最低环境要求默认浏览器目标基线v6 改变了默认 bundle 的目标浏览器。精确版本由以下 browserslist 查询在发布时钉住 0.5%, last 2 versions, Firefox ESR, not dead, safari 15.4, iOS 15.4v6.0.0 发布时的稳定快照stable-snapshot为目标版本相对 v5 的变化Node.js14从 12 提升Chrome109从 90 提升Edge121从 91 提升Firefox115从 78 提升SafarimacOS 与 iOS 均为 15.4从 macOS 14 / iOS 12.5 提升这一快照在仓库中的对应物是 .browserslistrc其中[stable]条目即官方文档标注的快照来源当前仓库 HEAD 的快照已随后续版本前移如node 14.0的[node]/[coverage]/[development]/[test]条目文件头部注释还提醒维护者在更新版本时同步代码库中所有标注#stable-snapshot的位置并保持文档与配置的一致性。IE 11 支持彻底移除IE 11 支持——包括遗留 bundle 以及所有与 IE 11 相关的代码——在 v6 中被完全移除。这一举措减小了 Material UI 的 bundle 体积并简化了后续开发。如果业务仍必须支持 IE 11只能停留在 v5 的 legacy bundle但该 bundle 不再接收任何更新或缺陷修复。最低 React 版本v6 支持的最低 React 版本为17.0.0与 v5 相同。这一点可以从源码依赖中得到印证packages/mui-material/package.json 中声明的 peerDependencies 为react: ^17.0.0 || ^18.0.0 || ^19.0.0react-dom同理Emotion 相关 peeremotion/react、emotion/styled均为可选项。升级 React 版本时可使用以下命令将version替换为目标版本# npm npm install reactversion react-domversion# pnpm pnpm add reactversion react-domversion# yarn yarn add reactversion react-domversionReact 18 及以下react-is 版本对齐如果项目使用 React 18 或更低版本需要将react-is强制解析resolution/override到与react相同的版本。以react18.3.1为例第 1 步安装react-is18.3.1# npm npm install react-is18.3.1# pnpm pnpm add react-is18.3.1# yarn yarn add react-is18.3.1第 2 步在package.json中设置 resolutions 或 overrides// npm / pnpm 使用 overrides { overrides: { react-is: ^18.3.1 } }// yarn 使用 resolutions { resolutions: { react-is: ^18.3.1 } }为什么需要这样做Material UI v6 依赖react-is19仓库中 packages/mui-material/package.json 与 packages/mui-utils/package.json 的依赖里可以看到react-is锁定在 19 系列而react-is19改变了 React 元素的识别方式。若停留在 React 18 及以下react-is版本不一致会引发 prop type 检查时的运行时错误将其强制对齐到 React 版本即可规避。最低 TypeScript 版本TypeScript 最低支持版本从 v3.5 提升到4.7。官方说明与 DefinitelyTyped 发布的类型types命名空间保持对齐且承诺不会在 Material UI 的次版本中变更最低支持版本同时建议不要使用低于 DefinitelyTyped 最低支持的 TypeScript 版本。若项目中包含以下包需要一并更新types/reacttypes/react-dom警告在继续下一步之前务必确认应用无错误地运行并提交本次变更。破坏性变更全览官方定位为v6 设计目标是引入尽可能少的破坏性变更。主要包括浏览器支持更新、Node.js 版本提升与 UMD bundle 移除——这些更新使 Material UI 包体积减小 2.5MB约占 v5 总体积的 25%。官方提供了 codemod 来处理其中大部分变更见自动化迁移工具一节。UMD bundle 移除为与 React 19 移除 UMD 构建保持一致Material UI 同步移除了 UMD bundlemui/material包体积因此减少 2.5MB约总体积的 25%。如果需要 CDN 等替代安装方式请参阅仓库中的安装文档目录。AccordionSummary 被标题元素包裹为符合 W3C Accordion Pattern 标准AccordionSummary现在被默认包裹在h3标题元素中。这会影响依赖旧 DOM 结构与 CSS 特定性的自定义样式默认标题元素也可能与页面既有的标题层级冲突。若样式或 DOM 操作依赖旧结构需要更新以适配新的标题元素若默认标题与现有结构冲突可通过slotProps.heading.component更换标题元素Accordion slotProps{{ heading: { component: h4 } }} AccordionSummary expandIcon{ExpandMoreIcon /} aria-controlspanel1-content idpanel1-header Accordion /AccordionSummary AccordionDetails Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse malesuada lacus ex, sit amet blandit leo lobortis eget. /AccordionDetails /Accordion仓库源码 packages/mui-material/src/Accordion/ 目录Accordion.js、AccordionSummary/子目录等中可以看到当前实现沿用了这一 slot 结构。自 v6.3.0 起Summary 根元素改为button以修复“用标题元素包裹按钮”所产生的无效 HTML根元素现在是buttonSummary 内容与图标包裹层渲染为span。此前用div选择器为AccordionSummary编写样式的开发者需要更新选择器使用Typography默认渲染p承载文本的场景应替换为span可通过component属性实现Typography componentspan /。AutocompleteonInputChange 新增 reason 取值onInputChange回调的reason参数新增三个取值细化了原先由reset覆盖的三种场景blur焦点离开输入框时触发行为类似reset要求clearOnBlur为trueselectOption选择某个选项后输入值发生变化时触发removeOption多选模式下因对应选项被选中而移除 chip 时触发。它们与既有的input、reset、clear取值并存。Chip按 Esc 键不再失焦早期版本中用户按 Esc 键时 Chip 会丢失焦点与其他按钮类组件行为不一致。v6 中 Chip 会按预期保留焦点。若必须保持旧行为可自行添加onKeyUp处理import * as React from react; import Chip from mui/material/Chip; export default function ChipExample() { const chipRef React.useRef(null); const keyUpHandler (event) { if (event.key Escape chipRef.current) { chipRef.current.blur(); } }; return ( Chip labelChip Outlined variantoutlined ref{chipRef} onKeyUp{keyUpHandler} / ); }Divider垂直方向渲染 div 而非 hr按 WAI-ARIA 规范垂直方向的 Divider 现在渲染带相应可访问性属性的div而不是hr。若 CSS 中针对hr标签写过样式需要同步调整。源码层面可以直接验证这一行为packages/mui-material/src/Divider/Divider.js 中的组件选择逻辑为component children || orientation vertical ? div : hr即垂直或含子元素时用div其余情形水平、无子元素仍用hr并配合roleseparator。推荐改用导出的dividerClasses工具类代替标签选择器-import Divider from mui/material/Divider; import Divider, { dividerClasses } from mui/material/Divider; const Main styled.main({ - hr: { [ .${dividerClasses.root}]: { marginTop: 16px, }, });Grid2稳定化与 API 重构Grid2原名Unstable_Grid2在 v6 中更新并正式稳定化带来以下变化去掉 Unstable 前缀-import { Unstable_Grid2 as Grid2 } from mui/material; import { Grid2 } from mui/material;-import Grid from mui/material/Unstable_Grid2; import Grid from mui/material/Grid2;size 与 offset 属性重命名v5 中 size/offset 属性以主题断点命名默认主题下为xs/sm/md/lg/xl及对应的xsOffset/smOffset/…v6 统一改名为size和offsetGrid - xs{12} - sm{6} - xsOffset{2} - smOffset{3} size{{ xs: 12, sm: 6 }} offset{{ xs: 2, sm: 3 }} 若所有断点取值相同可直接用单一值-Grid xs{6} xsOffset{2} Grid size{6} offset{2}size的布尔值true撑满可用空间改名为字符串grow-Grid xs Grid sizegrow迁移命令npx mui/codemodlatest v6.0.0/grid-v2-props path/to/folder警告运行该 codemod 之前必须先把导入从mui/material/Unstable_Grid2改为mui/material/Grid2。自定义断点同样适用新写法-Grid mobile{12} mobileOffset{2} desktop{6} desktopOffset{4} Grid size{{ mobile: 12, desktop: 6 }} offset{{ mobile: 2, desktop: 4 }}自定义断点需把断点名作为参数传给 codemodnpx mui/codemodlatest v6.0.0/grid-v2-props path/to/folder --jscodeshift--muiBreakpointsmobile,desktopdisableEqualOverflow 属性移除v5 中 Grid 会溢出父容器v6 中 Grid 被正确地约束在父容器 padding 之内因此不再需要disableEqualOverflow属性-Grid disableEqualOverflow GridGrid 间距机制改为 CSS gapv5 中 Grid 项的盒模型包含间距v6 中改用 CSSgap属性实现间距项的位置本身不发生变化。官方警告这可能导致应用布局出现意料之外的变化但强烈建议直接采纳新行为而不是设法复刻旧模式因为新实现更可预测、更现代。容器宽度更新后的 Grid 默认不再撑满容器全宽。需要全宽时使用sx-Grid container Grid container sx{{ width: 100% }} // 或者若 Grid 的父级是 flex 容器 -Grid container Grid container sx{{ flexGrow: 1 }}ListItembutton 等属性移除ListItem上自 v5 起已弃用的autoFocus、button、disabled、selected属性在 v6 中被移除。button属性的替代方案是使用ListItemButton其余被移除的属性也在该组件上可用-ListItem button / ListItemButton /迁移 codemodnpx mui/codemodlatest v6.0.0/list-item-button-prop path/to/folder由于ListItem不再支持这些属性相关类名一并移除应改用listItemButtonClasses-import { listItemClasses } from mui/material/ListItem; import { listItemButtonClasses } from mui/material/ListItemButton; -listItemClasses.button listItemButtonClasses.root -listItemClasses.focusVisible listItemButtonClasses.focusVisible -listItemClasses.disabled listItemButtonClasses.disabled -listItemClasses.selected listItemButtonClasses.selectedButtonLoadingButton 合并入标准 Button自mui/materialv6.4.0起Lab 中的LoadingButton被移除加载状态成为标准Button的一部分-import { LoadingButton } from mui/lab; import { Button } from mui/material;-import LoadingButton from mui/lab/LoadingButton; import Button from mui/material/Button;这一合并可从仓库源码印证packages/mui-material/src/Button/Button.js 中Button组件直接解构并处理loading、loadingPosition属性并据此派生loading、loadingPosition*等类名与loadingIndicator/loadingWrapperslot说明加载能力已内置于标准Button而非独立组件。Typographycolor 不再是系统属性Typography的color属性不再是 system prop主题回调形式需改用sx-Typography color{(theme) theme.palette.primary.main} Typography sx{{ color: (theme) theme.palette.primary.main }}背景是system props 整体被弃用、推荐sx属性详见 migrating-from-deprecated-apis。color属性仍可接收部分主题色名称Typography colortextSecondarySecondary text/TypographyuseMediaQuery 类型清理以下已弃用类型在 v6 中移除MuiMediaQueryList改用 lib.dom.d.ts 中的MediaQueryListMuiMediaQueryListEvent改用MediaQueryListEventMuiMediaQueryListListener改用(event: MediaQueryListEvent) void。影响测试的破坏性变更波纹效果v6 提升了 ripple 效果的性能因此涉及带波纹组件的测试可能需要更新。若使用testing-library/react的fireEvent模拟交互需要将其包裹在act中并await以避免 React 警告- fireEvent.click(button); await act(async () fireEvent.mouseDown(button));受影响的组件包括所有按钮、Checkbox、Chip、Radio Group、Switch、Tabs。影响类型的破坏性变更Boxcomponent属性已从BoxOwnProps中移除因为Box类型本身已包含它。若你在使用styled函数包装Box可能受影响两种解决方案方案一改用div结果等价-const StyledBox styled(Box) const StyledDiv styled(div) color: white; ;方案二将 styled 返回值断言为typeof Boxconst StyledBox styled(Box) color: white; -; as typeof Box;稳定化 APICssVarsProvider 与 extendThemeCssVarsProvider与extendTheme正式稳定可以去掉实验性前缀-import { experimental_extendTheme as extendTheme, Experimental_CssVarsProvider as CssVarsProvider } from mui/material/styles; import { extendTheme, CssVarsProvider } from mui/material/styles;theme.applyStyles按颜色模式附加样式v6 新增工具theme.applyStyles()用于替代theme.palette.mode条件判断来为特定颜色模式附加样式const MyComponent styled(button)(({ theme }) ({ padding: 0.5rem 1rem, border: 1px solid, - borderColor: theme.palette.mode dark ? #fff : #000, borderColor: #000, ...theme.applyStyles(dark, { borderColor: #fff, }) }))配套 codemodnpx mui/codemodlatest v6.0.0/styled path/to/folder-or-file npx mui/codemodlatest v6.0.0/sx-prop path/to/folder-or-file npx mui/codemodlatest v6.0.0/theme-v6 path/to/theme-file说明如果项目有自定义主题请将v6.0.0/theme-v6指向包含自定义styleOverrides的文件运行没有自定义主题则可忽略该 codemod。自动化迁移工具mui/codemodv6 的大部分破坏性变更都有对应 codemod 可自动处理。命令形如npx mui/codemodlatest codemod paths...v6.0.0 系列在仓库中的实现位于 packages/mui-codemod/src/v6.0.0/包括Codemod作用源码位置v6.0.0/grid-v2-props迁移 Grid2 的 size/offset 属性支持--muiBreakpoints自定义断点grid-v2-props.jsv6.0.0/list-item-button-prop将ListItem button迁移为ListItemButtonlist-item-button-prop.jsv6.0.0/styled将 styled 中的palette.mode判断改写为applyStylesstyled-v6.jsv6.0.0/sx-prop将 sx 属性中的palette.mode判断改写为applyStylessx-v6.jsv6.0.0/theme-v6处理主题文件中的styleOverridestheme-v6.jsv6.0.0/all组合执行 v6 全部 codemodv6-all.js从 codemod.js 的 CLI 定义看它还支持以下常用选项便于安全地执行迁移--dry试运行不实际修改任何文件--parser指定 jscodeshift 解析器默认tsx--print将转换结果打印到 stdout便于开发调试--jscodeshift向 jscodeshift 透传高级参数如上文--jscodeshift--muiBreakpointsmobile,desktop的用法--packageName指定在 import 中查找的包名默认mui/material。每个 codemod 目录下都附带test-cases/*.actual.js/*.expected.js与.test.js测试文件例如 grid-v2-props 的测试用例 覆盖了标准断点、自定义断点及 package.json 依赖更新等场景——运行 codemod 后若对某处改写存疑可以对照这些用例确认预期行为。完整 codemod 清单见 packages/mui-codemod/README.md。弃用项可以按自己的节奏处理使用 v6不要求立即清理所有弃用 API。可以在 弃用 API 迁移页 中按需逐项处理这些弃用项将在下一个主版本中移除。后续步骤迁移到 Pigment CSS完成 v6 升级后即可着手迁移到 Pigment CSS以获得 RSC 支持与更小的 bundle 体积具体步骤参见 Pigment CSS 迁移指南。升级操作清单速查确认 React ≥ 17推荐升级到 18/19 的对应稳定版并同步升级mui/icons-material、mui/system、mui/lab、mui/material-nextjs、mui/styled-engine-sc、mui/utils至 6.0.0MUI X 包保持原版本若使用 React ≤ 18安装与 React 同版本的react-is并在package.json配置overridesnpm/pnpm或resolutionsyarn将 TypeScript 提升至 ≥ 4.7同步更新types/react、types/react-dom确认应用无错后提交修改导入mui/material/Unstable_Grid2→mui/material/Grid2运行 codemodgrid-v2-props、list-item-button-prop、styled、sx-prop、theme-v6建议先加--dry预览人工处理 codemod 无法覆盖的变更Accordion 标题结构、Divider 的hr选择器、LoadingButton→Button loading、Typography color回调 →sx、BoxOwnProps相关的styled(Box)、useMediaQuery类型更新受 ripple 性能改进影响的测试actawait检查浏览器/Node.js 支持范围是否满足新的.browserslistrc基线Node 14、Chrome 109、Edge 121、Firefox 115、Safari 15.4如仍依赖 IE 11则应停留在 v5。【免费下载链接】material-uiMaterial UI: Comprehensive React component library that implements Googles Material Design. Free forever.项目地址: https://gitcode.com/GitHub_Trending/ma/material-ui创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考