news 2026/9/14 11:34:37

umi Ant Design Pro 示例工程实战:基于 @umijs/max 的企业级前端脚手架

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
umi Ant Design Pro 示例工程实战:基于 @umijs/max 的企业级前端脚手架

umi Ant Design Pro 示例工程实战:基于 @umijs/max 的企业级前端脚手架

【免费下载链接】umiA framework in react community ✨项目地址: https://gitcode.com/GitHub_Trending/um/umi

examples/antd-pro-create是 umi 仓库中用于演示"用 Ant Design Pro 模板初始化项目后如何与 umi(max)体系协同工作"的完整示例工程。本篇以该工程的 README 为主线,逐条展开其环境准备、脚本体系与工程化配置,并结合 package.json 与 config 目录 的源码,讲清楚每个命令背后实际执行了什么、多环境变量如何影响开发服务,以及如何用 Cypress / Playwright 对工程做端到端验证。读完你可以直接在这个工程上启动、构建、校验与测试一个企业级中后台前端项目。

工程定位:workspace 内的 Pro 模板示例

该示例位于examples/下,是 pnpm workspace 的成员之一——pnpm-workspace.yaml 声明了packages/*examples/*等目录均为 workspace 包。它的 package.json 中关键依赖为:

{ "dependencies": { "antd": "^4.23.3", "react": "^17.0.0", "@ant-design/pro-components": "^2.3.13" }, "devDependencies": { "@umijs/max": "workspace:*", "umi-presets-pro": "^2.0.3" }, "engines": { "node": ">=12.0.0" } }

需要注意两点事实边界:

  • @umijs/max的版本是workspace:*,即引用的是本仓库packages/max中正在开发的版本,而不是 npm 上发布的版本。因此该示例的适用前提是:在 umi 仓库根目录通过 pnpm 安装依赖并构建本地包,脱离 monorepo 单独运行会拿不到workspace:*依赖。
  • 技术栈组合为 React 17 + antd 4 + Pro Components 2,属于 Pro 模板的经典版本组合,配置与 API 以此版本为准。

环境准备

README 给出的原始步骤是安装依赖:

npm install # 或 yarn

由于本仓库采用 pnpm workspace 管理(见 pnpm-lock.yaml 与 pnpm-workspace.yaml),实际在本仓库内准备该示例环境时,应在仓库根目录执行 pnpm 安装,让@umijs/max: workspace:*正确解析到本地包;examples/antd-pro-create目录内则按模板原意执行npm install/yarn即可。

脚本体系:从 README 四件套到完整脚本表

README 中最核心的内容是"Provided Scripts"一节,声明了四个基础命令。对照当前 package.json 的scripts字段,可以给出完整的脚本表(README 的四件套全部在其中,且已明显扩充):

脚本实际命令作用
start/devnpm run start:dev启动开发服务(带REACT_APP_ENV=dev UMI_ENV=dev
start:devcross-env REACT_APP_ENV=dev UMI_ENV=dev max dev以 dev 环境启动 max 开发服务
start:no-mockcross-env MOCK=none UMI_ENV=dev max dev关闭 mock 数据启动
start:pre/start:testcross-env REACT_APP_ENV=pre\|test ...切换 API 环境启动
buildmax build生产构建
analyzecross-env ANALYZE=1 max build构建并输出产物体积分析
previewmax preview --port 9527本地预览构建产物
deploynpm run build && npm run gh-pages构建并发布到 gh-pages
serveumi-serve用 umi-serve 托管静态产物
lintlint:js && lint:prettier && tscESLint + Prettier + 类型检查
lint:fixeslint --fix --cache --ext .js,.jsx,.ts,.tsx --format=pretty ./src自动修复 lint 问题
tsctsc --noEmit仅做 TypeScript 类型检查
i18n-removepro i18n-remove --locale=zh-CN --write移除指定语言的 i18n 文案
openapimax openapi基于 OpenAPI schema 生成 services 与 mock
e2e/e2e:cicypress run/ start-server-and-test 组合Cypress 端到端测试
playwrightplaywright install && playwright testPlaywright 端到端测试
test:e2enode ./tests/run-tests.js旧的 e2e 运行入口(tests 目录)

README 四个基础命令与现状的差异

  • 启动npm start在当前 package.json 中被定义为一个转发链:startdevstart:dev,最终执行cross-env REACT_APP_ENV=dev UMI_ENV=dev max dev。也就是说"启动"并不是裸跑max dev,而是同时注入了两个环境变量(见下文"多环境"小节)。
  • 构建npm run buildmax build,与 README 描述一致;额外的analyze脚本在其上加了ANALYZE=1用于产物分析。
  • 代码风格检查:README 中的npm run lint/npm run lint:fix对应现状。当前lint脚本实际是三段式:ESLint 检查(lint:js)→ Prettier 校验(lint:prettier,只检查src/**/*)→tsc --noEmit类型检查,比 README 描述的"style check"覆盖面更广;lint:fix则只对./src执行eslint --fix。此外还有提交期钩子:lint-staged配置声明了**/*.{js,jsx,ts,tsx}走 ESLint、其余源码/样式/文档走prettier --write
  • 测试:README 写的是npm test,但当前 package.json 中没有名为test的脚本——可以推断这是文档相对模板的滞后。当前仓库中真正可执行的端到端测试入口是e2ecypress run)、e2e:ci(先起服务再跑 Cypress)与playwright,另外保留了test:e2e指向 tests/run-tests.js 的旧入口。

多环境变量与代理:REACT_APP_ENV 驱动的开发服务

start:dev/start:pre/start:test/start:no-mock这组脚本的差别只在环境变量,而变量如何影响运行时,体现在两处源码中:

  1. config/config.ts 读取process.env.REACT_APP_ENV来决定使用哪套代理配置:
const { REACT_APP_ENV } = process.env; export default defineConfig({ // ... proxy: proxy[REACT_APP_ENV || 'dev'], // ... });
  1. config/proxy.ts 按dev/test/pre三个键组织代理规则,其中test环境把/api/前缀的请求转发到远程 API 并做了路径重写:
export default { dev: {}, test: { '/api/': { target: 'https://proapi.azurewebsites.net', changeOrigin: true, pathRewrite: { '^': '' }, }, }, pre: { '/api/': { /* 指向预发环境 */ }, }, };

这与start:no-mock中的MOCK=none形成互补:MOCK=none关闭的是 umi 内置 mock 机制,而REACT_APP_ENV切换的是代理目标。两者共同决定了开发模式下接口数据的来源。代理只在开发期生效,构建产物中不生效,这一点在 proxy.ts 文件头部注释中有明确说明。

构建、预览与部署

  • max build:生产构建。配合analyze脚本(ANALYZE=1 max build)可输出体积分析。
  • max preview --port 9527:本地预览构建产物,端口 9527 与下文 CI 流程中的端口保持一致。
  • deploybuild && gh-pages -d dist,把产物发布到 GitHub Pages(依赖gh-pages包)。
  • serve:使用umi-serve托管静态产物,适合快速起一个生产样式的静态服务。

端到端测试:Cypress 与 Playwright 双轨

该示例同时配置了两套 E2E 工具,可从源码确认具体行为:

  • Cypress:cypress.config.ts 中baseUrlhttp://localhost:${PORT}(默认 8000),retries.runMode设为 3,并在 Windows 平台上把defaultCommandTimeout放宽到 60 秒。CI 脚本e2e:ci通过start-server-and-test preview http://127.0.0.1:9527 cypress:ci实现"先起 preview 服务、就绪后再跑测试"的编排;另有e2e:dev:cistart启动开发服务并以http://127.0.0.1:9527/__umi/api/status作为就绪探针——这个 status 接口正是 umi 开发服务提供的健康检查端点。测试用例位于 cypress/e2e 与 src/e2e 下。
  • Playwright:playwright.config.ts 声明了 chromium 与 firefox 两个项目,CI 下开启forbidOnly与 2 次重试,并对首次重试开启 trace,便于失败定位。
  • 单元测试tests/目录保留了run-tests.js/setupTests.js,对应test:e2e脚本,属于模板遗留的旧式 runner 入口。

配置骨架:config 目录与运行时配置

理解这些脚本"为什么这么写",需要看工程的两层配置:

静态配置(config/),入口为 config/config.ts,在 umi 基础项(hashroutesthemeignoreMomentLocaleproxyfastRefresh)之外,开启了 max 的一组插件:

model: {}, // 数据流 initialState: {}, // 全局初始状态 layout: { locale: true, ...defaultSettings }, // ProLayout 布局 locale: { default: 'zh-CN', antd: true, baseNavigator: true }, antd: {}, request: {}, // 基于 axios + useRequest 的统一请求 access: {}, // 基于 initialState 的权限 presets: ['umi-presets-pro'], openAPI: [ { schemaPath: join(__dirname, 'oneapi.json'), requestLibPath: "import { request } from '@umijs/max'", mock: false }, { schemaPath: 'https://.../openapi.json', projectName: 'swagger' }, ],

其中openAPI配置正是npm run openapimax openapi)脚本的输入:基于本地 oneapi.json 与远端 swagger schema 生成 services 与 mock,减少样板代码。

路由集中在 config/routes.ts,覆盖了 Pro 模板的典型形态:/user/loginlayout: false脱离主布局;/admin路由通过access: 'canAdmin'声明权限约束;/重定向到/welcome*通配落到 404 页。布局默认值(navTheme、主色#1890fflayout: 'mix'等)则来自 config/defaultSettings.ts。

运行时配置(src/app.tsx),src/app.tsx 导出了 max 约定的三个运行时钩子,与静态配置形成闭环:

  • getInitialState:非登录页时调用queryCurrentUser拉取用户信息,失败则重定向到/user/login,并把fetchUserInfocurrentUsersettings一起放进全局初始状态;
  • layout:返回RunTimeLayoutConfig,注入水印、右侧内容区RightContent、页脚Footer、未登录守卫(onPageChange),并通过childrenRender挂载SettingDrawer实现主题动态切换(这依赖 config.ts 中theme: { 'root-entry-name': 'variable' }的设置,注释里明确说明只有variable模式才支持动态主题);
  • request:展开errorConfig(来自 src/requestErrorConfig.ts)提供统一错误处理。

小结与适用前提

  • 该示例展示的是模板初始化后的完整工程形态:多环境启动脚本、构建/预览/部署链路、三段式 lint、双 E2E 工具,均已在 package.json 中落地,可按脚本表直接照抄到自建项目。
  • 适用前提:依赖 React 17 + antd 4 的 Pro 模板版本,且@umijs/max在本仓库中为workspace:*,脱离 monorepo 运行时需将其替换为可发布的 npm 版本。
  • 若要在仓库内验证:根目录安装依赖后,在examples/antd-pro-create下依次执行npm run start:dev(开发)、npm run lint(质量检查)、npm run build && npm run preview(构建预览)、npm run e2e(Cypress 验证),即可覆盖 README 所述的全部工作流。

【免费下载链接】umiA framework in react community ✨项目地址: https://gitcode.com/GitHub_Trending/um/umi

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/14 11:31:39

构建 kt-kernel 时 CMake 报 “CUDA compiler not found“ 怎么修复?

构建 kt-kernel 时 CMake 报 "CUDA compiler not found" 怎么修复? 【免费下载链接】ktransformers A Flexible Framework for Experiencing Heterogeneous LLM Inference/Fine-tune Optimizations 项目地址: https://gitcode.com/GitHub_Trending/ktr/…

作者头像 李华
网站建设 2026/9/14 11:28:41

SpringBoot酒店预约系统开发实战与优化

1. 项目概述:SpringBoot酒店预约系统开发实录 去年接手的一个酒店管理系统项目让我对SpringBoot在实际业务中的应用有了全新认识。这个基于SpringBoot 2.7的酒店预约系统,从需求分析到上线部署共耗时三个月,期间踩过的坑和积累的经验值得系统…

作者头像 李华