首页
/ 从 v5 Alpha 破局到 MUI X 起航:Material UI 2020 Q3 季度迭代全复盘

从 v5 Alpha 破局到 MUI X 起航:Material UI 2020 Q3 季度迭代全复盘

2026-09-06 18:50:40作者:俞予舒Fleming

本篇文章基于 Material UI 官方博客 2020 Q3 Update(发布于 2020-10-14)整理成文。它记录的是 MUI 从 v4 迈向 v5 的关键转折期:v5.0.0-alpha 系列破晓而出、7 个组件由实验室晋升为核心、MUI X 与新样式引擎落地、公司首次为商业化组件招兵买马。读完本文,你将完整掌握这次迭代的来龙去脉,理解"unstyled 组件 + Emotion 样式引擎 + dynamic variant API"如何一步步演化为今天 MUI 组件体系的基石,并能在当前仓库中找到每项能力的源码与佐证。

一、这一季度发生了什么

自 2020 年 6 月以来,MUI 团队经历了一个"非常密集"的季度:启动下一代大版本 v5 的 alpha 预发布、把实验室组件成批地推向核心库、发布全新的商业化数据表格组件、迁移测试与类型基础设施、并着手重建底层样式方案。这篇更新是团队对社区的一次系统化汇报,涵盖产品、公司两个维度,并对 Q4 2020 立下了明确的 roadmap intent(详见原始博文,本文以下划线文件为骨架展开)。

文章全貌分三部分:

  1. Product:v5 alpha 进度、组件晋级、FocusTrap、React 17 兼容、dynamic variant API、MUI X data grid、TypeScript 迁移、react-testing-library 迁移、unstyled 组件、Emotion 样式引擎、无障碍与公开路线图。
  2. Company:两名新全职工程师加入、Q2→Q3 的增长指标。
  3. Q4 2020 roadmap intent:社区、企业、公司三线的目标清单。

二、v5.0.0-alpha:新一代大版本的第一次预发布

本季度伊始,团队发布了 v5.0.0-alpha.1,这是 Material UI 下一个主版本的第一批预发布版本。随后又连续放出 11 个 alpha 预发布。在 v5 的 alpha 开发阶段,核心任务是:

  • 按计划实施破坏性变更(breaking changes),季度结束时已完成约一半的既定变更;
  • 同步开发新特性

这条从 v4 到 v5 的迁移主线,随后在 2020 年底的 《MUI Core v5 迁移指引》 与 2021 年的 Q1 Update 中得到延续。就当前仓库而言,v5 之后的演进在 CHANGELOG.md 中有完整的版本轨迹可供回溯。

说明:博主原文中的版本号、团队规模、npm 下载量等均为 2020 年 Q3 的历史快照;本文提及它们仅用于还原当时语境,不代表当前仓库的实时指标。

三、7 个实验室组件晋升为核心

本季度最大的一批"毕业仪式",是把以下 7 个此前长期停留在实验室(@mui/lab)打磨的组件正式提升到核心库(@mui/material):

组件 用途
Alert 页面内即时反馈的警告条
Autocomplete 自动补全输入框
Pagination 分页控件
Rating 评分
Skeleton 骨架屏占位
SpeedDial 悬浮快捷操作按钮
ToggleButton 开关按钮组

博文称:虽然这些组件仍保留少量计划中的破坏性变更,但团队相信它们已经达到与核心组件一致的质量水平。这一判断在当前仓库的源码组织中得到印证——上述 7 个组件如今都拥有独立的实现目录与类型声明,例如:

四、FocusTrap:实验室新增的焦点管理组件

MUI 在实验室中引入了 FocusTrap,用于管理其后代元素的焦点。其典型场景是实现 Modal、Dialog 之类的遮罩层:当弹层打开时,焦点不允许"逃逸"到弹层之外,键盘 Tab 键的循环也应被限制在弹层内部。

原博文附带了一段演示视频(trap-focus.mp4,仓库路径 docs/public/static/blog/2020-q3-update/trap-focus.mp4),直观展示焦点被锁定的行为。此后 FocusTrap 能力被下放到 Base UI / MUI Base 系列并成为 ModalPopoverMenu 等组件内部无障碍实现的关键一环——这正是"可访问性是基础设施而非锦上添花"这一设计取向的例证。

五、为 React 17 的到来做准备

v5 alpha 阶段同时承担了为 React 17(2020 年 8 月发布 RC)做兼容的工作。博文指出大部分工作集中在:

  • 更好的事件处理:React 17 将事件从 document 上挂载改为挂载到根容器,MUI 内部的合成事件与原生事件协作逻辑需要随之调整;
  • 测试基础设施升级:让整个测试套件可以分别跑在 React 的 latestnext 版本上,从而提前暴露兼容性问题;
  • 加强 StrictMode 支持:当时最后几个遗留问题正随着样式引擎的重写一并解决(下文详述)。

这种"测试矩阵跟跑最新/下一个 React 版本"的做法,在今天的仓库中延续为 test/、各包的 vitest.config.* 以及 react-next.diffscripts/react-next.diff)等基础设施。

六、Dynamic Variant API:从主题中直接扩展组件变体

这是本季度最有代表性的 API 设计之一。新 API 允许开发者在主题层面为 Material UI 组件声明全新的 variant,而无需包裹组件、无需覆盖样式钩子。原博文给出的 Button 示例(原文使用当时命名 createMuiTheme,后续版本已更名为 createTheme):

// 为特定 props 组合声明应套用的样式
const theme = createTheme({
  components: {
    MuiButton: {
      variants: [
        {
          props: { variant: 'dashed', color: 'secondary' },
          styles: {
            border: `4px dashed ${red[500]}`,
          },
        },
      ],
    },
  },
});

// 可选:保持类型安全
declare module '@mui/material/Button' {
  interface ButtonPropsVariantOverrides {
    dashed: true;
  }
}

// 直接使用!
<Button variant="dashed" color="secondary" />;

理解这个 API 的几个要点:

  1. 支持多属性组合匹配props 不仅可以是单个属性(如 variant: 'dashed'),还可以是属性组合(如同时约束 variantcolor)。这在"不同变体试图修改同一个 CSS 属性从而产生冲突"时尤为重要——组合匹配让优先级和冲突消解更加可控。
  2. 类型安全是可选的但强烈推荐ButtonPropsVariantOverrides 这类接口在 Button 相关类型 中随处可见;仓库中的 Alert.d.ts 同样导出了 AlertPropsVariantOverridesAlertPropsColorOverrides,说明这套 overrides 声明机制已经成为所有组件的通用约定。
  3. 它在内部如何工作:从当前源码看,主题里声明的 variants 会与组件自身样式内嵌的 variants(见 Button.js)一起参与渲染解析。@mui/systempreprocessStyles.ts 提供了佐证:它会把样式对象中的 variants 字段拆出来做预处理(internal_serializeStyles),对函数式 variant style 进行序列化,从而把主题/组件中静态声明的 variants 统一接入 styled 引擎的运行时解析管线。
  4. 设计意图:博文明确说明,这一变化是"让自定义设计系统落地更容易"方向的一部分;团队还展望未来能对接 Figma 的 Variants 能力。

Button 中的实际用法进一步展示该机制已被组件内部广泛使用——containedtextoutlined 等内置 variant 均以 { props, style } 对象数组形式声明,任何新增的 props 组合都可以沿用同一套数据结构。

七、MUI X 与 Data Grid:商业化路线正式起航

本季度最重要的战略动作,是发布了 data grid 组件的第一个 alpha 版本(代码名"X"),并正式宣布为之开辟独立仓库 mui/mui-x 的路线。

关键事实链(均出自原博文,仓库内亦有对应沉淀):

  • MUI 早在 一年前2019 年 9 月更新)就预告过要构建这个组件的意图;
  • 团队刻意不做"一个月就能交差的简单版本",而是瞄准"best-in-class 的 React 数据表格"。首个 alpha 距离初始 commit(2020-03-15)经历了约 6 个月开发(该版本面向 v4);
  • 组件呈现了强大的渲染能力(博文配图展示 100,000 行数据的运行效果,见下文配图);
  • 为支撑这样的目标,需要采用双许可模型:易实现且能被开源模式长期维系的特性走 MIT 开源协议;更高级的特性走商业付费许可。为补齐领域专家,团队新开了职位,数月后 Damien Tassone 加入并牵头 data grid(详见 相关入职介绍)。

从仓库视角看,data grid 相关产品如今独立演化于 MUI X 体系;本次仓库内的 docs/datadocs/pages 中仍保留了大量 data grid 文档与宣传页面供读者研究。需要强调的是:当前本仓库(material-ui core)本身并不包含 data grid 的实现代码,博文只是宣布了该方向的启动。

MUI X data grid 首个 alpha 版本的运行界面,可渲染 10 万行数据
Data grid 首个 alpha 版本的运行画面(100,000 行数据)

八、TypeScript 迁移与基础设施重构

两条并行的代码基础设施主线:

  1. material-ui 仓库局部 TypeScript 化:迁移部分代码到 TypeScript,主要动机是为接收用 TypeScript 编写的 date picker 组件做准备(这些组件来自将被归档的 mui/material-ui-pickers)。迁移后仓库的 TS 占比可以从配图(typescript-mui.png,仓库路径 docs/public/static/blog/2020-q3-update/typescript-mui.png)直观看出。
  2. mui-x 仓库从第一天起就全面使用 TypeScript(见配图 typescript-mui-x.png)。

十年之后的今天再看,这条迁移决策的影响极其深远:当前仓库的 packages 下,mui-materialmui-systemmui-utils 等核心包源码均已全面 TypeScript 化(.ts/.tsx.d.ts 并存),配合 TYPESCRIPT_CONVENTION.md 形成规范闭环。

九、测试体系迁移:react-testing-library

MUI 用 15 个月时间逐步把测试体系从 enzyme 迁往 react-testing-library(第一个用例见 2019 年 PR #15732)。到 2020 年 10 月,react-testing-library 在 npm 上的周下载量已超过 enzyme。原博文配图 react-testing-library.png 记录了这一趋势。

这次迁移的意义在于测试哲学的改变:从"组件内部实现细节"转向"用户可见行为"。当前仓库的测试体系正是这一方向的延续——各包目录下的 *.test.js / *.test.tsxtest/ 下的回归测试(regressions)与端到端(e2e)测试共同构成分层验证体系。

十、Unstyled Components:把"无样式"做成第一步

v5 的另一个第一次迭代成果,是无样式组件(unstyled components)。以 Slider 为例,实验室中出现了不带任何样式的版本(@mui/lab/SliderUnstyled):

import SliderUnstyled from '@mui/lab/SliderUnstyled';

原博文给出的数据:unstyled 版按 gzip 压缩后约 5.2 kB,而独立使用时的 styled 版约 26 kB(当时包体积数据,非当前版本数值)。无样式组件最适合"想要完全自定义外观,但不想重写 JavaScript 逻辑与无障碍逻辑"的场景;MUI 也在回应大型企业的诉求——它们希望在抽象层级上再往下一层,以获得更多控制权。

博文同时回顾了此前实验过的 headless(纯 hooks)方案,例如 useAutocompleteusePagination。团队之所以把 unstyled 作为优先方向,是为了给下一件事(新的样式解决方案)铺路——样式引擎可以被替换,而不动组件的 JS/无障碍内核。

十一、新样式解决方案:从 JSS 到 Emotion / styled-components

v5 把样式引擎从 JSS 换成 Emotion,同时允许已使用 styled-components 的应用直接替换(代码层面只依赖 styled API,通过别名映射实现零额外包体开销,示例见当时的 styled-components CodeSandbox/CRA demo)。

博文给出两个直接的收益:

  • 包体积下降:相比 JSS 节省 2 kB+(gzip);如果应用本来就已使用 styled-components 或 Emotion,可省约 14 kB(gzip);
  • 开启动态样式 props:为动态 color props、variant props 及核心组件上的新 style props 铺平道路。

演示配图 emotion.pngstyled-components.png 展示了同一个 Slider 分别在 Emotion 与 styled-components 引擎下渲染的对比。

从当前仓库看,这套架构的遗迹依然清晰:

也就是说,博文里"换引擎如换挡"的设计,今天已经沉淀为 mui-styled-enginemui-styled-engine-sc 双包并存的工程事实。

十二、无障碍投入与公开路线图

  • 无障碍:本季度集中修复了 13 个 accessibility 相关 bug。结合上文 FocusTrap、Alert 等组件的设计,可看出无障碍是被当成核心工程质量来管理的;
  • 路线图透明化:MUI 正式引入季度公开路线图,分别为每个 MUI Core 产品和 MUI X 产品维护公开的 project board,社区可以用 👍 表情在 GitHub issues 上表达优先级诉求(这一惯例延续至今,公开项目面板见仓库文档/README 引导)。

十三、公司进展:新成员与增长快照

两位新全职开发者的加入是本季度公司在人力资源上的核心事件:

  • Marija Najdova:来自微软 Fluent-UI React 团队,加入后让社区团队提速,详见入职介绍博文
  • Danail Hadjiatanasov:来自金融科技行业,加入企业团队并协助 Damien 推进 data grid,详见入职介绍博文

Q2 2020 → Q3 2020 的增长指标(数据均出自原博文,属历史快照):

指标 Q2 2020 Q3 2020
npm 月下载量 510 万 600 万
GitHub Stars 59.0k 61.6k
GitHub 贡献者 1,825 1,934(平均每天新增约 1 名)
全职开发者 新增 2 名

此外,相对 react-dom 的下载占比配图 react-share.png 显示 MUI 在 React 生态内部的渗透率同步上行——团队将其解读为"React 在增长,我们在 React 生态内部也在增长"。

十四、Q4 2020 路线图意图

博文末尾以"我们会尽力,但不做承诺"的务实口吻列出了 Q4 计划:

Community(社区线)

  • 执行公开 roadmap 上的全部事项;
  • 简化 v4 → v5 的迁移体验;
  • 持续通过 GitHub issues 的 👍 数量做优先级排序。

Enterprise(企业线)

  • 完成与设计机构上季度启动的品牌更新合作:更新公司 branding、重新设计首页、为商业化包设计营销页面;
  • 执行 MUI X 公开 roadmap;
  • 同样借助 issues 的 👍 机制排序。

Company(公司线)

  • 可能招聘一名"会写代码的全职设计师"(对应解决 issue #22485);
  • 受 COVID-19 影响,公司全员线下团建(retreat)暂缓,希望 Q2 2021 能成行。

其中"简化 v4→v5 迁移体验"的目标,最终以 v5 迁移文档 和大量 codemod(见 packages/mui-codemod)的形式落地——这也是本次季度更新与仓库现状之间最直接的呼应。

结语:一份理解 MUI 架构基因的季度切片

回顾 Q3 2020 这份更新,可以清晰地看到 MUI 此后数年技术路线的几个原点:变体可主题化(dynamic variant)、样式引擎可插拔、无样式组件与逻辑/无障碍解耦、商业化组件与开源组件分层运营。它们在当时是 alpha 中的新能力,而在今天的 packages/mui-materialpackages/mui-systempackages/mui-styled-engine 源码中,依然能找到一脉相承的实现。对想深入理解 MUI 组件体系"为什么长成这样"的开发者而言,这篇季度更新是最有价值的原始史料之一。

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