搞前端后台项目的朋友应该都绕不开 Ant Design Pro 这个名字。最近我把 Ant Design Pro V4 和 V5 完整地各装了一遍,顺便把 Block 的接入方式研究了个透。这篇记录先写安装部分:怎么用 Yarn 把 ADP V4、V5 装好,以及 V4 里那套 Block 机制怎么全量接入,V5 里 Block 变成了什么形态。以下内容全是实操记录,不绕弯子,直接给可复制的命令和流程,新手可以照抄,老手可以当排查手册用。
其实光是“安装”这件事,坑远比想象多:Node 版本不对、Yarn 版本不对、Block 源拉不下来,甚至装完启动直接白屏。涉及版本号、包管理器、项目脚手架三个环节,任何一个错位都会让整个流程停下来。我会尽量把每个步骤背后的原因也讲清楚,免得你遇到变体又不知道怎么办。
1. 环境准备与选型思路
1.1 为什么要用 Yarn 而不是 npm
Ant Design Pro 的官方文档、Umi 的官方文档,所有命令示例默认都是 Yarn。这不是情怀,是因为 V4 时代 Umi 3 的插件体系、Block 下载脚本和 Yarn 的 workspace 特性配合得更好,V4 项目的依赖锁定也完全围绕 yarn.lock 展开。用 npm 当然也能装,但你会发现后面执行 umi block add 的时候,官方示例脚本、Block 内部依赖的解析方式全都按 Yarn 的目录结构来写,npm 装出来的 node_modules 结构在某些场景下会让 Block 的依赖合并出问题。实测下来,最稳的方案就是全程只用一个包管理器,不要混用 npm 和 yarn,否则 lock 文件互相覆盖,会凭空多出一堆版本冲突。
1.2 Yarn 版本选择:1.x 才是正道
这里必须先强调一下:装 Ant Design Pro 的时候,Yarn 请使用 1.x 版本(也叫 classic),不要用 Yarn 2+(Berry)。原因很简单,Berry 默认的 PnP 模式不走 node_modules,而 Umi 3 / Umi 4 的插件和 Block 机制都默认基于 node_modules 展开,PnP 的解析方式会导致不少插件找不到模块。如果你已经装了 Berry 也没关系,执行yarn config set nodeLinker node-modules切回 node_modules 模式,或者更干脆用 corepack 把版本固定回 1.x。
我建议直接用 nvm 管理 Node,然后全局安装 Yarn 1.x。这里有个细节:Yarn 1.x 对 Node 版本也有要求,过高版本的 Node(比如 20+)在安装某些旧依赖时会报 OpenSSL 相关错误,等下我会在问题排查部分专门讲。
1.3 Node 版本的血泪教训
版本对应关系大概是这样的:
- ADP V4(Umi 3):Node 12 ~ 16 最佳,20 大概率 OpenSSL 报错。
- ADP V5(Umi 4):Node 14 ~ 18 最佳,20 也可以但可能需要额外运行参数。
- Yarn 1.x:Node 14 ~ 20 多数情况下能跑,但老项目还是建议用 LTS。
我实际调试时的组合是:V4 用 Node 14.21.3 + Yarn 1.22.19,V5 用 Node 18.20.4 + Yarn 1.22.22。两个项目分开目录,各用各的 Node 版本,避免来回升降级。如果你同时维护两代项目,强烈建议用 nvm alias 给不同目录配好默认版本,不然切换项目时终端里经常忘记切换 Node,装到一半才发现版本不对,又得清掉重来。
2. Ant Design Pro V4:Yarn 安装与 Block 全量接入
2.1 用 Yarn 初始化 V4 项目
V4 的安装命令很简单,核心就是通过 create umi 脚手架生成项目骨架。执行顺序:
# 先确认当前 Node 版本 node -v # 创建项目(注意项目名用小写,避免驼峰) yarn create umi my-adp-v4这里会进入交互式命令行,模板选择的时候,除了基础的 umi 模板,还要选择 Ant Design Pro 相关选项。如果你是第一次操作,很容易在这里被交互界面绕晕:选择 ant design pro 那一项之后,还会有是否启用 TypeScript、是否加载全部区块等好几个子问题。我建议第一个项目先选择 TypeScript + 完整功能,后面再单独研究 Block。
初始化完成后,进入项目目录安装依赖:
cd my-adp-v4 yarn这一步大概会拉下 300 多个依赖包,耗时取决于网络状况。装完之后先不要急着启动,先把后续的 Block 配置做好,一起验证。
2.2 V4 的 Block 机制与配置前提
V4 的项目基于 Umi 3,而 Block 并不是 Umi 3 的原生概念,它是 Ant Design Pro 在 Umi 插件体系上扩展出来的一套“页面级代码片段下载”机制。说人话就是:官方维护了一个叫 pro-blocks 的仓库,里面放了各种现成的页面模块(比如基础表单、高级表格、文件上传、图形编辑器这类),可以通过命令直接拉进你的项目并自动注册路由。
要让 Block 命令可用,需要先做两件事。
第一件事:确认项目里有config/config.ts这个文件,并且在配置里加上 Block 相关字段。通常会在block这个顶级配置下设置defaultGitUrl,指向 pro-blocks 的仓库地址。示例:
export default defineConfig({ block: { defaultGitUrl: 'https://github.com/ant-design/pro-blocks.git', }, })第二件事:确认src/.umi目录存在。Block 命令运行时依赖 Umi 的临时文件目录,如果项目还没启动过,很多情况下src/.umi是空的或者不存在,直接执行 block add 会报错。稳妥做法是先yarn start启动一次,让它生成完整的运行时目录,再停掉做后续操作。
这两件事是很多人在 V4 上折腾半天 Block 装不上的最常见原因,配置文件和运行时目录缺一不可。
2.3 逐个添加 Block 的实操记录
Block 的添加有两种方式。第一种是交互式:
yarn umi block add运行后会列出 pro-blocks 仓库里的所有区块,方向键选择,回车确认。但交互界面在大批量接入时效率不高,而且如果块比较多,列表展示会比较吃内存。第二种方式是直接指定 git 地址:
# 指定仓库里的某个目录 yarn umi block add https://github.com/ant-design/pro-blocks/tree/master/BasicForm这种方式最终会把区块的 src 目录下代码复制到当前项目的src/pages/下,并自动在路由配置文件里注册对应路径。
如果你想一次性把多个 Block 都装进来,可以用一个循环脚本批量拉取。我自己实际用的是一组手动命令按顺序执行,因为每个 block 拉下来之后最好都跑一遍类型检查,确认没有依赖缺失再继续下一个。比较常用的 Block 有:
- BasicForm:基础表单
- AdvancedForm:高级表单
- BasicList:基础列表
- TableList:表格列表模板
- AccountCenter:个人中心
- AccountSettings:个人设置
- EditorFlow:流程编辑器
- EditorMind:脑图编辑器
- Monitor:监控台
把这些 Block 全部拉下来之后,项目 pages 目录会变得很大,路由也会变长,所以如果你的项目规模比较小,不建议全量接入,只接自己真正要用的几个页面模板即可。全量接入的代价是首屏构建时间显著上升,这一点要有心理准备。
2.4 启动验证与目录结构说明
装完 Block 之后,再次执行:
yarn start重点观察终端输出的路由注册日志,正常情况下会看到刚才添加的 Block 路由逐个出现在生成的 router 配置里。访问首页后,左侧菜单会自动出现对应菜单项。
此时项目目录结构大概是这样的:
├── config │ ├── config.ts │ └── routes.ts ├── src │ ├── pages │ │ ├── BasicForm │ │ ├── AdvancedForm │ │ ├── TableList │ │ └── ... │ ├── components │ ├── services │ ├── models │ └── umi.ts ├── package.json └── yarn.lock这里有个要点:Block 拉下来的代码不是像普通依赖那样放在 node_modules 里,而是直接变成你项目源代码的一部分,所以之后你可以完全自由地修改它,就等于官方给了你一堆可以直接改的现成页面脚手架。这是 Block 机制和后面 V5 模板机制的核心差异,也是理解两代项目差异的关键。
3. Ant Design Pro V5:从安装到模板迁移
3.1 用 Yarn 创建 V5 项目
V5 的初始化方式跟 V4 不太一样,现在的推荐姿势有两种:一种是通过 pro-cli 来创建,另一种是直接克隆官方仓库。我先把 pro-cli 方式写出来:
# 先安装 pro-cli yarn global add @ant-design/pro-cli # 然后用它创建 pro create my-adp-v5如果你不想装全局工具,也可以用 Umi 的 create 命令:
yarn create umi my-adp-v5创建时选择 Ant Design Pro 模板即可。不管哪种方式,最终生成的都是同一个官方项目模板,接下来进入目录装依赖:
cd my-adp-v5 yarn yarn startV5 的依赖数量比 V4 还要多,编译用的是 Webpack 5,首次冷启动基本上要一分钟以上,这是正常的。还有一点:V5 默认使用 React 18,如果你后面要接一些只兼容 React 16 的第三方库,安装时要特别留意 peer 依赖的提示。
3.2 Block 机制在 V5 中的变化
V5 全名叫 Ant Design Pro 5.x,底层从 Umi 3 换到了 Umi 4。最明显的变化是:Block 这个“官方命令式下载”的能力被移除了。在 V5 里执行umi block add是没有意义的,因为插件体系里已经没有这个命令了。
官方现在的思路是“模板仓库 + 手动复制”。官方维护了一个 pro-blocks 仓库,里面仍然是那些页面模板,但它们不再通过命令注入到你的项目,而是需要你打开仓库,找到对应模板,把src目录下的代码复制到你自己的项目里,手动改路由、手动配菜单。
我第一次升级到 V5 时也被这个变化恶心到了,因为 V4 里一条命令能搞定的事,现在要手动做很多步。但冷静下来之后,我理解官方的考虑:Block 自动注入虽然快,但它会让项目结构变得不那么透明,出现路由重复、代码覆盖这类问题时比较隐蔽;改成手动复制之后,每一行代码都是你自己放进去的,结构更可控,也没有了跨仓库依赖解析的负担。
3.3 手动导入页面模板的完整流程
在 V5 中导入一个模板,实际流程分五步。
第一步,打开 pro-blocks 仓库,进入你要的模板目录,比如BasicForm,把src下的代码下载下来。
第二步,把代码放入项目的src/pages/BasicForm目录下,注意同时复制对应的services、models、components这几种子目录,如果模板里引用了公共组件,还需要检查公共组件目录里是否已有对应文件。
第三步,改路由。V5 的路由配置在config/routes.ts(或约定式路由位置),手动增加一条路由记录:
{ path: '/basic-form', component: './BasicForm', name: '基础表单', }第四步,修改菜单。在 V5 中菜单一般由 routes 自动生成,所以只要路由加上了,菜单一般也会跟着出现;但如果项目用了src/app.tsx里的 layout 配置,注意给路由配置加上 icon 字段,不然菜单上没有图标。
第五步,安装模板自己的依赖。打开模板的package.json,找到它额外依赖的包名,然后:
yarn add <package-name>@<version>这一步最容易漏,漏掉的结果就是页面运行时报模块不存在,或者样式错乱。我习惯的做法是把模板的 package.json 和项目当前 package.json 放到一起,人工比对 dependencies 差异,一次性补齐。
这套流程走完,页面上就能正常访问模板了。虽然步骤多,但胜在完全透明、可控。
4. V4 与 V5 安装差异对照与版本演进分析
4.1 安装命令与工程结构对照
整理一下两者的安装路径:
| 对比项 | V4 | V5 |
|---|---|---|
| 脚手架命令 | yarn create umi | pro create 或 yarn create umi |
| 底层框架 | Umi 3 + React 16 | Umi 4 + React 18 |
| Block 支持 | 命令式注入 | 已移除,手动复制 |
| 推荐 Node | 12 ~ 16 | 14 ~ 18 |
| 构建工具 | Webpack 4 | Webpack 5 |
| 初始化耗时 | 相对较短 | 更长,依赖更多 |
表格看着简单,实际工程差异主要集中在两点。
第一,V4 的目录约定更零散,pages、models、services 各自一摊,Block 自动注入时也会往这些目录里塞东西;V5 把很多东西收敛到 src 下更统一的约定里,同时对 hooks、request 配置做了更大程度的封装。
第二,路由配置方式有调整,V4 的配置可以集中在 config.ts 里写,V5 支持多种路由来源,并且对权限、菜单、布局的联动更紧密。
4.2 Block 从自动到手动的原因
Block 机制在 V4 中看似好用,实际有隐患。我举个例子:Block A 依赖了某个工具的某个版本,Block B 依赖了同一个包的另一版本,自动注入不会帮你处理这种内部冲突,装多了之后经常出现“明明报错文件在里面,但就是运行不了”的问题,只能靠人肉排查。手动复制之后,每个模板的依赖都由你自己决定加不加、控制版本,反而把这类问题从“隐性问题”变成了“显性问题”。
另外,自动下载 Block 对网络依赖比较强,pro-blocks 仓库有时候会拉取超时。这不是工具的问题,而是仓库源本身就不稳定。如果你想在 V4 上全量接 Block,优先把仓库源切到镜像,或者直接把模板压缩包下载到本地再接入,过程会省心很多。
4.3 当前版本选择的建议
如果你是从零开始的新项目,我更推荐直接上 V5。原因很实际:
- V5 的脚手架默认就带完整的权限配置、布局配置和国际化方案,开箱即用度更高。
- 官方维护的重心已经全部转到 V5,V4 的 issue 基本不再有人回应。
- React 18 + Webpack 5 的生态兼容性更好,未来的依赖升级路径更明确。
- V5 虽然没有 Block,但自带页面模板数量足够覆盖一整套后台管理系统,绝大多数业务场景不需要全量导入。
如果你是在维护历史项目,V4 也完全可以继续用,只要 Node 和 Yarn 版本稳定,V4 项目照样跑得很好。但建议不要在 V4 上新增 Block 了,把现有功能守住,比引入不确定的新依赖更划算。
5. 高频问题与排查实录
5.1 Yarn 安装卡死与源配置
最典型的问题是执行 yarn 时长时间停在 “Building fresh packages...” 或 “Resolving...” 不动。排第一的原因就是默认源不稳定,换下源:
yarn config set registry https://registry.npmmirror.com换完再删掉 node_modules 重新安装。这里有个细节,yarn.lock 里如果存的是旧源地址,换源后依然会尝试去旧地址拉取,需要同时把 yarn.lock 删掉重新解析,虽然慢一点,但比卡死好。
5.2 Node 版本导致 OpenSSL 报错
Node 17 以上在安装某些老依赖时会报类似这样的错误:
Error: error:0308010C:digital envelope routines::unsupported原因很简单:新版本 Node 默认使用 OpenSSL 3,而老版本 Webpack 4 里用到的加密算法解析方式对不上。解决方法是给 Node 加启动参数:
# 临时方案 export NODE_OPTIONS=--openssl-legacy-provider yarn start注意这是临时方案,只适合本机调试。更干净的办法还是用 nvm 切到 Node 14 或 16,从根上绕开问题。
5.3 Block 添加时报路径不存在
如果你在执行umi block add时报找不到模板目录,先看两处。
第一,确认项目的config/config.ts里有block.defaultGitUrl配置。
第二,确认你输入的区块名跟 pro-blocks 仓库里的目录名完全一致,大小写都要一致。
还有一个隐蔽点:如果项目还没启动过,src/.umi 目录里缺少运行时文件,block 命令可能会报内部错误。我的习惯是先yarn start启动一次,完全没问题后再执行 block 操作,这个问题就再也没出现过。
5.4 V5 启动白屏的快速定位
V5 项目 start 起来页面白屏,大概率是运行时配置没加载出来,常见的有三种情况。
一是src/app.tsx里配了 request 的错误兜底逻辑,接口访问失败直接抛异常,可以先注释掉 layout 里的相关逻辑逐段排查。
二是路由表里引用了不存在的组件路径,V5 对路径错误很敏感,一旦引用路径不对,直接不出组件。
三是权限组件没接入好,访问控制的判断逻辑如果读不到用户信息,页面会被挡在入口。
遇到白屏,先开浏览器控制台看有没有报错,有报错顺藤摸瓜;没有报错就去看 network 面板有没有接口请求异常。这是我排查 V5 问题的通用顺序。
5.5 依赖冲突的一劳永逸思路
当你同时维护 V4 和 V5 项目时,最闹心的就是两个项目各自的依赖版本互相干扰。我的做法是:
- 不同项目安装依赖时,进入项目先执行
yarn,不要用yarn install --force强行装。 - 两个项目的 package.json 中如果出现同包不同版本,人为把版本统一到较新项目使用的版本数字。
- 遇到实在没法统一的,可以单独给某个包加 resolutions 字段固定版本,这是 Yarn 提供的隐性覆盖机制,用的时候要非常清楚包的实际接口是否兼容。
这套思路执行下来,维护成本会低很多。
结尾
我在实际折腾这两代项目的过程中,最有感触的一点是:安装和 Block 接入的坑,八成出在环境上,而不是代码上。Yarn 版本、Node 版本、仓库源这三个基础变量必须先把稳,后面的事才会顺畅。如果你是从 V4 直接跳到 V5,Block 机制的消失肯定会让你别扭几天,但不要急着去找替代脚本,先手动复制一套页面模板,你会更快理解 V5 的设计哲学,后面跟着版本演进才不会老是踩坑。下一个坑大概率在权限和路由联动上,等我把那部分踩完再写一篇记录——V5 的权限配置是真的有东西。