编者按:本文作者是蚂蚁集团前端工程师云谦,整体介绍了 Umi 4 的新功能以及下一步规划,欢迎查阅~
Umi 4 现在可以在 npm 上使用了!详见:umijs.org。
2 个月前,我们已在蚂蚁集团内部发布了基于 Umi 4 的内网框架,目前上线近 100 应用,基于此,Umi 4 的主体功能已非常稳定,这也是第一次我们先在内网发布后在社区正式发布。
Umi 4 有什么新功能?
相比 Umi 2 到 Umi 3,Umi 4 有着更宏大的目标,开发时间也长了很多,同时带来的变化是巨大的。
多构建引擎。 Umi 4 同时支持 Vite 和 Webpack 两种构建方式,并尽量确保他们之间功能的一致性,让开发者可以通过一行配置进行切换。可能有些同学会喜欢 dev 用 vite,build 用 webpack 这样的组合。同时我们也在探索包括 ESMi 在内的其他构建方案的探索。
export default { vite: {} }
默认快。 默认快是多维度的,我们通过 MFSU V3 + Webpack 5 缓存解 Dev 时编译慢的问题;内网还有通过 Webpack 5 物理缓存和 CD 平台结合解 Build 时编译慢的问题;有使用 esbuild 做 js 和 css 的压缩器、配置和 MOCK 文件的读取、jest 的 transformer,让除构建之外的其他环节也飞快;此外还有运行时速度也有考虑。
MFSU V3。(👈点击查看详细介绍) Umi 3 的 MFSU 大家可能多少有接触过,虽然有用,但 DX 不够好。用的时候会遇到一些坑,以至于很多同学都掌握了一项特殊技能,遇到问题时 rm -rf src/.umi。大家可能会遇到 monorepo 不支持、热更新导致 Tab 卡死、请求多导致页面打开慢、一些语法不支持的问题。以上问题在 MFSU V3 中全解!基于此,我们非常有信心地在 Umi 4 中默认开启 MFSU 功能。当然,如果你不喜欢,会保留手动配置 mfsu: false 关闭的口子。同时,MFSU V3 还可脱离 Umi 独立使用。
Umi Max。 这是内部 Bigfish 框架的对外版本,解我们自己的问题,同时也给社区另一个集中化框架的选择,定位是中后台框架,包含了中后台相关的大量最佳实践的插件。如果有定制需求,大家可以参考他来实现内网框架的定制,比如快手团队就有基于 Umi 4 的框架定制,还有 Alita 也是基于 Umi 定制的面向移动端的框架。
$ npm i @umijs/max -D
React Router 6。(👈点击查看详细介绍)我们升级了路由方案到 React Router 6,喜忧参半。好消息是,React Router 6 是 Remix 的基础库,面向框架层做了很多优化,路由实现层更优雅,Umi 得以删除大量路由渲染的代码;坏消息是,带来不少 Break Change,比如之前父路由渲染子路由用 children,得换成 。
- { props.children } + <Outlet />
支持 Vue。 Umi 4 中提供了 Vue 支持,记得我在 Umi 2 时画过一张架构图,其中就有 Vue 的一环,Umi 3 时也有过尝试,但那会 Vue 3 还不太成熟,接入时遇到不少坑,这个坑今天总算是补上了。此功能由社区同学操刀,只需装载一个 preset 即可切换到 Vue。
export default { presets: ['@umijs/preset-vue'], };
默认最快的 CSR 请求。(👈点击查看详细介绍)项目构建快解的是 DX 问题,但同时也应该关注 UX。Client Loader 的目的是让应用加载默认快,避免 React 项目经典的 Render-Then-Fetch 的加载瀑布流问题。效果见下图,示例项目的从 9s 降到 6s,这 6s 还是之前截的图,上了 Preload 功能之后其实已更快。
export default function() { // 使用请求数据 useClientLoaderData() } // 声明请求 export function clientLoader() {}
白盒稳定的 Lint。(👈点击查看详细介绍) Umi 4 里内置了我们精挑细选的 lint 规则,只有质量类不开可能会导致项目问题的规则,不包含风格类的规则,不包含 TypeScript 中 type-aware 类的规则,这类规则需要跑整个项目,会导致性能问题;同时,我们通过 @rushstack/eslint-pach 的方式锁定了 config 里找 plugin 的规则,确保规则是长期稳定的。
SSR。 Umi 4 重写了 SSR 功能,目前此功能还在 beta 阶段,请勿将其用于生产环境。Umi 4 的 SSR 有以下特点,1)server 代码的构建基于 esbuild,所以极快,2)请求的处理类似 next.js 的 getServerSideProps 和 remix 的 loader,只在服务端跑,3)基于 react 18 的 suspense 和 renderToPipeableStream。实现原因,部署层目前仅实现了 vercel 的 adapter。这里有个简单的 Todos 示例:https://test-vercel-chencheng.vercel.app/
export default { ssr: { platform: 'vercel' } }
API 路由。 Umi 4 约定 src/api 目录下存放的 Serverless Function 格式的文件即为 API 路由。这部分路由会打包成不同平台支持的 Serverless Function 产物。场景比如带 token 的 API 调用、动态数据源、基于 Notion API 的 Blog、Hackernews Clone 等等。基于此,Umi 能做的事的边界就大了很多。不再只是写写中后台,实现静态页面。
export default { apiRoute: {}, }
微生成器。 此概念来自 Modern.js。Modern.js 引入很多新概念,其中「微生成器」还是非常贴切的。他包含两个功能,1)小型脚手架,2)功能的开启与关闭。Umi 3 虽然也有 generate 命令,但只包含功能 1。Umi 4 拓展了下 generate(alias 为 g)命令。除了支持更多类型的小型脚手架生成,还支持功能的开启与关闭,以及比如 Monorepo、react 和 antd 版本等的功能切换。
$ npx umi g ? Pick generator type › - Use arrow-keys. Return to submit. ❯ 创建页面 -- Create a umi page by page name 创建组件 -- . 创建 mock 代码 -- . 创建 model 代码 -- . 启用 Prettier -- Setup Prettier Configurations 启用 Jest -- Setup Jest Configuration 启用 E2E 测试 -- . 启用 Tailwind CSS -- Setup Tailwind CSS configuration 启用 SSR -- . 启用 Low Import 研发模式 -- . 启用权限方案 -- . 启用 Monaco 编辑器 -- . 关闭 Dva 数据流 -- Configuration, Dependencies, and Model Files for Dva 关闭 MFSU -- . 切换为 Monorepo 项目 -- . 切换 React 为 18 -- . 切换 Antd 为 5 -- .
除此之外,我们还有非常多小而美的 DX 改进。
自动 https。 Umi 4 的 https dev server 的实现基于 mkcert,启动过程中会基于 hosts 自动生成对应的 key 和 cert。开发者除了安装前置的 mkcert,其他无需关心。
浏览器里的构建进度条。 如果首次构建没有完成就在浏览器里打开,你会看到一个构建进度条,支持 webpack 多实例,支持 MFSU,完成初始构建后会自动跳转到项目页。
Terminal 中的日志。 有些开发者会更希望在命令行里看到项目里通过 console 输出的日志,比如我。因为命令行日志不会随着刷新而失效,大家可能都经历过一些一闪而过的页面,想截屏都难;同时命令行日志还可以做物理存储,导出后可以方便他人排查。此功能复刻自 https://github.com/patak-dev/vite-plugin-terminal。
import { terminal } from 'umi'; terminal.log(`Some info from the app`);
然后就可以在命令行中看到日志,
umi.js 产物调试。 不知大家是否会有这样的需求,开发项目时发现一些比较复杂的问题时,需要调整构建产物的代码。而 Bigfish 基于 webpack-dev-server,在 dev 阶段所有文件都存于内存中,没有物理文件的形式,并不方便直接修改后验证效果。如果大家用 Umi 4,可以把 umi.js 等产物文件保存到项目根目录,然后可以直接修改即生效。
项目级插件:plugin.ts。 为进一步降低项目中使用插件的门槛,Bigfish 4 中约定项目根目录下的 plugin.ts 为插件,开发者可在此直接调用插件 API,无需注册,支持 TypeScript。有了这个文件,我们可以在项目级做很多事。比如,
import { IApi } from 'umi'; export default (api: IApi) => { // 比如修改 HTML api.modifyHTML($ => { return $; }); // 比如在入口的 umi.ts 中添加代码 api.addEntryCodeAhead(() => [`console.log('entry code ahead')`]); api.addEntryCode(() => [`console.log('entry code')`]); // 比如在构建完成时做额外的事 api.onBuildComplete((opts) => {}); // 比如在启动阶段做额外的事 api.onStart((opts) => {}); // 比如校验每个 JavaScript/TypeScript 代码 api.onCheckCode((args) => {}); // 比如动态修改路由 api.modifyRoutes((routes) => {}); }
deadCode 检测。项目中通常会有未使用的文件或导出,Umi 4 中通过配置 deadCode: {} 即可在 build 阶段做检测。如有发现,会有类似信息抛出。
Warning: There are 3 unused files: 1. /mock/a.ts 2. /mock/b.ts 3. /pages/index.module.less Please be careful if you want to remove them (¬º-°)¬.
Umi UI 卷土重来? 日常排查问题时,很多 Umi 框架的内部状态是看不到的,比如插件启用情况、appData 元数据、修改过的最终配置、修改过的最终 webpack 配置、修改过的最终路由、MFSU 的 module graph 信息等。Umi 4 提供了 /__umi/ 路由,dev 阶段可用,效果见下图。定位是开发辅助,大家也可以理解为是「丐版 Umi UI」。
我可以做什么?
Umi 4 发布之后,我可以做什么?
① 升级项目到 Umi 4
② 使用 Umi 4 开启新项目
③ 参与贡献
④ 订阅 NewsLetter
⑤ 交流反馈群
Ant Design Pro 已完成到 Umi 4 的升级,不日将发布新版本。
除了使用 Umi,也非常欢迎大家参与贡献 Umi。你的贡献会直接影响到蚂蚁 10000+ 应用和 3000+ 开发者,以及非常多社区的项目和同学。感兴趣的同学可认领入门任务,1 个 PR 即可加入 Umi Contributor 群,和来自五湖四海的朋友们畅聊前沿技术。
我们新增了 NewsLetter 服务,如果大家希望即时了解 Umi 的最新进展,可在新官网 umijs.org 右下角进行订阅。
交流反馈群详见「feedback.umijs.org」。
下一步?
Umi 4 发布后,Umi 团队今年还会在以下方向发力。
① 2022 版的最佳实践
② MFSU V4:更快的 MFSU
③ Father 4 和 dumi 2:新一代组件研发方案
④ ESMi:面向未来的 Bundless 构建方案
⑤ DX(开发体验)和速度
技术方向有迭代才会更有生命力,今年最佳实践会出一个新的版本,包含现有方案的改进,以及新的 monorepo、icon、请求、数据流等方向的最佳实践;MFSU V4 已有思路,会在现有基础上进一步提升其稳定性和速度;Father 4 和 Dumi 2 是新一代的组件研发方案;面向未来的 ESMi Bundless 方案的性能问题已有曙光,预计也会在今年和大家见面;最后,DX 和速度(包括编译时和运行时)是 Umi 一直会关注的点。