前置说明
这里我使用的是 simple 版本,并结合 antd pro 脚手架搭建(现在默认使用为 umi4 版本):
虽然这个文档好像已经好久没有更新了。
config 文件:
config.ts
// https://umijs.org/config/
import { defineConfig } from '@umijs/max';
import { join } from 'path';
import defaultSettings from './defaultSettings';
import proxy from './proxy';
import routes from './routes';// env 可以 .env 配置 也可以 cross-env 配置
const { REACT_APP_ENV = 'dev', NODE_ENV } = process.env;export default defineConfig({/*** @name 开启 hash 模式* @description 让 build 之后的产物包含 hash 后缀。通常用于增量发布和避免浏览器加载缓存。* @doc https://umijs.org/docs/api/config#hash*/hash: true,/*** @name 兼容性设置* @description 设置 ie11 不一定完美兼容,需要检查自己使用的所有依赖* @doc https://umijs.org/docs/api/config#targets*/// targets: {// ie: 11,// },/*** @name 路由的配置,不在路由中引入的文件不会编译* @description 只支持 path,component,routes,redirect,wrappers,title 的配置* @doc https://umijs.org/docs/guides/routes*/// umi routes: https://umijs.org/docs/routingroutes,/*** @name 主题的配置* @description 虽然叫主题,但是其实只是 less 的变量设置* @doc antd的主题设置 https://ant.design/docs/react/customize-theme-cn* @doc umi 的theme 配置 https://umijs.org/docs/api/config#theme*/theme: {// 如果不想要 configProvide 动态设置主题需要把这个设置为 default// 只有设置为 variable, 才能使用 configProvide 动态设置主色调'root-entry-name': 'variable',},/*** @name 标题* @doc https://umijs.org/docs/api/config#title*/title: 'Ant Design Pro',/*** @name 路由模式* @doc https://umijs.org/docs/api/config#history*/history: {type: 'browser',},/*** @name 开发环境使用 sourcemap* @doc https://umijs.org/docs/api/config#devtool*/devtool: NODE_ENV === 'development' ? 'source-map' : false,/*** @name moment 的国际化配置* @description 如果对国际化没有要求,打开之后能减少js的包大小* @doc https://umijs.org/docs/api/config#ignoremomentlocale*/ignoreMomentLocale: true,/*** @name 代理配置* @description 可以让你的本地服务器代理到你的服务器上,这样你就可以访问服务器的数据了* @see 要注意以下 代理只能在本地开发时使用,build 之后就无法使用了。* 这里的 proxy 是 proxy.ts 文件 表示 key 值(REACT_APP_ENV)为环境变量,value 值为代理地址。* @doc 代理介绍 https://umijs.org/docs/guides/proxy* @doc 代理配置 https://umijs.org/docs/api/config#proxy*/proxy: proxy[REACT_APP_ENV as keyof typeof proxy],/*** @name 快速热更新配置* @description 一个不错的热更新组件,更新时可以保留 state*/fastRefresh: true,//============== 以下都是max的插件配置 ===============/*** @name 数据流插件* @@doc https://umijs.org/docs/max/data-flow*/model: {},/*** 一个全局的初始数据流,可以用它在插件之间共享数据* @description 可以用来存放一些全局的数据,比如用户信息,或者一些全局的状态,全局初始状态在整个 Umi 项目的最开始创建。* @doc https://umijs.org/docs/max/data-flow#%E5%85%A8%E5%B1%80%E5%88%9D%E5%A7%8B%E7%8A%B6%E6%80%81*/initialState: {},/*** @name layout 插件* @doc https://umijs.org/docs/max/layout-menu*/layout: {locale: true,// 布局默认设置文件...defaultSettings,},/*** @name moment2dayjs 插件* @description 将项目中的 moment 替换为 dayjs* @doc https://umijs.org/docs/max/moment2dayjs*/moment2dayjs: {preset: 'antd',plugins: ['duration'],},/*** @name 国际化插件* @doc https://umijs.org/docs/max/i18n*/locale: {// default zh-CNdefault: 'zh-CN',antd: true,// default true, when it is true, will use `navigator.language` overwrite defaultbaseNavigator: true,},/*** @name antd 插件* @description 内置了 babel import 插件* @doc https://umijs.org/docs/max/antd#antd*/antd: {},/*** @name 网络请求配置* @description 它基于 axios 和 ahooks 的 useRequest 提供了一套统一的网络请求和错误处理方案。* @doc https://umijs.org/docs/max/request*/request: {},/*** @name 权限插件* @description 基于 initialState 的权限插件,必须先打开 initialState* @doc https://umijs.org/docs/max/access*/access: {},/*** @name <head> 中额外的 script* @description 配置 <head> 中额外的 script*/headScripts: [// 解决首次加载时白屏的问题{ src: '/scripts/loading.js', async: true },],//================ pro 插件配置 =================presets: ['umi-presets-pro'],/*** @name openAPI 插件的配置* @description 基于 openapi 的规范生成serve 和mock,能减少很多样板代码* @doc https://pro.ant.design/zh-cn/docs/openapi/*/openAPI: [{requestLibPath: "import { request } from '@umijs/max'",// 或者使用在线的版本// schemaPath: "https://gw.alipayobjects.com/os/antfincdn/M%24jrzTTYJN/oneapi.json"schemaPath: join(__dirname, 'oneapi.json'),mock: false,},{requestLibPath: "import { request } from '@umijs/max'",schemaPath: 'https://gw.alipayobjects.com/os/antfincdn/CA1dOm%2631B/openapi.json',projectName: 'swagger',},],mfsu: {strategy: 'normal',},esbuildMinifyIIFE: true,requestRecord: {},
});
defaultSettings.ts
布局的默认设置
import { ProLayoutProps } from '@ant-design/pro-components';/*** @name*/
const Settings: ProLayoutProps & {pwa?: boolean;logo?: string;
} = {navTheme: 'light',// 拂晓蓝colorPrimary: '#1890ff',layout: 'mix',contentWidth: 'Fluid',fixedHeader: false,fixSiderbar: true,colorWeak: false,title: 'Ant Design Pro',pwa: true,logo: 'https://gw.alipayobjects.com/zos/rmsportal/KDpgvguMpGfqaHPjicRK.svg',iconfontUrl: '',token: {// 参见ts声明,demo 见文档,通过token 修改样式//https://procomponents.ant.design/components/layout#%E9%80%9A%E8%BF%87-token-%E4%BF%AE%E6%94%B9%E6%A0%B7%E5%BC%8F},
};export default Settings;
oneapi.json
mock 的一套接口文档。
{"openapi": "3.0.1","info": {"title": "Ant Design Pro","version": "1.0.0"},"servers": [{"url": "http://localhost:8000/"},{"url": "https://localhost:8000/"}],"paths": {"/api/currentUser": {"get": {"tags": ["api"],"description": "获取当前的用户","operationId": "currentUser","responses": {"200": {"description": "Success","content": {"application/json": {"schema": {"$ref": "#/components/schemas/CurrentUser"}}}},"401": {"description": "Error","content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorResponse"}}}}}},"x-swagger-router-controller": "api"},"/api/login/captcha": {"post": {"description": "发送验证码","operationId": "getFakeCaptcha","tags": ["login"],"parameters": [{"name": "phone","in": "query","description": "手机号","schema": {"type": "string"}}],"responses": {"200": {"description": "Success","content": {"application/json": {"schema": {"$ref": "#/components/schemas/FakeCaptcha"}}}}}}},"/api/login/outLogin": {"post": {"description": "登录接口","operationId": "outLogin","tags": ["login"],"responses": {"200": {"description": "Success","content": {"application/json": {"schema": {"type": "object"}}}},"401": {"description": "Error","content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorResponse"}}}}}},"x-swagger-router-controller": "api"},"/api/login/account": {"post": {"tags": ["login"],"description": "登录接口","operationId": "login","requestBody": {"description": "登录系统","content": {"application/json": {"schema": {"$ref": "#/components/schemas/LoginParams"}}},"required": true},"responses": {"200": {"description": "Success","content": {"application/json": {"schema": {"$ref": "#/components/schemas/LoginResult"}}}},"401": {"description": "Error","content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorResponse"}}}}},"x-codegen-request-body-name": "body"},"x-swagger-router-controller": "api"},"/api/notices": {"summary": "getNotices","description": "NoticeIconItem","get": {"tags": ["api"],"operationId": "getNotices","responses": {"200": {"description": "Success","content": {"application/json": {"schema": {"$ref": "#/components/schemas/NoticeIconList"}}}}}}},"/api/rule": {"get": {"tags": ["rule"],"description": "获取规则列表","operationId": "rule","parameters": [{"name": "current","in": "query","description": "当前的页码","schema": {"type": "number"}},{"name": "pageSize","in": "query","description": "页面的容量","schema": {"type": "number"}}],"responses": {"200": {"description": "Success","content": {"application/json": {"schema": {"$ref": "#/components/schemas/RuleList"}}}},"401": {"description": "Error","content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorResponse"}}}}}},"post": {"tags": ["rule"],"description": "新建规则","operationId": "addRule","responses": {"200": {"description": "Success","content": {"application/json": {"schema": {"$ref": "#/components/schemas/RuleListItem"}}}},"401": {"description": "Error","content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorResponse"}}}}}},"put": {"tags": ["rule"],"description": "新建规则","operationId": "updateRule","responses": {"200": {"description": "Success","content": {"application/json": {"schema": {"$ref": "#/components/schemas/RuleListItem"}}}},"401": {"description": "Error","content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorResponse"}}}}}},"delete": {"tags": ["rule"],"description": "删除规则","operationId": "removeRule","responses": {"200": {"description": "Success","content": {"application/json": {"schema": {"type": "object"}}}},"401": {"description": "Error","content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorResponse"}}}}}},"x-swagger-router-controller": "api"},"/swagger": {"x-swagger-pipe": "swagger_raw"}},"components": {"schemas": {"CurrentUser": {"type": "object","properties": {"name": {"type": "string"},"avatar": {"type": "string"},"userid": {"type": "string"},"email": {"type": "string"},"signature": {"type": "string"},"title": {"type": "string"},"group": {"type": "string"},"tags": {"type": "array","items": {"type": "object","properties": {"key": {"type": "string"},"label": {"type": "string"}}}},"notifyCount": {"type": "integer","format": "int32"},"unreadCount": {"type": "integer","format": "int32"},"country": {"type": "string"},"access": {"type": "string"},"geographic": {"type": "object","properties": {"province": {"type": "object","properties": {"label": {"type": "string"},"key": {"type": "string"}}},"city": {"type": "object","properties": {"label": {"type": "string"},"key": {"type": "string"}}}}},"address": {"type": "string"},"phone": {"type": "string"}}},"LoginResult": {"type": "object","properties": {"status": {"type": "string"},"type": {"type": "string"},"currentAuthority": {"type": "string"}}},"PageParams": {"type": "object","properties": {"current": {"type": "number"},"pageSize": {"type": "number"}}},"RuleListItem": {"type": "object","properties": {"key": {"type": "integer","format": "int32"},"disabled": {"type": "boolean"},"href": {"type": "string"},"avatar": {"type": "string"},"name": {"type": "string"},"owner": {"type": "string"},"desc": {"type": "string"},"callNo": {"type": "integer","format": "int32"},"status": {"type": "integer","format": "int32"},"updatedAt": {"type": "string","format": "datetime"},"createdAt": {"type": "string","format": "datetime"},"progress": {"type": "integer","format": "int32"}}},"RuleList": {"type": "object","properties": {"data": {"type": "array","items": {"$ref": "#/components/schemas/RuleListItem"}},"total": {"type": "integer","description": "列表的内容总数","format": "int32"},"success": {"type": "boolean"}}},"FakeCaptcha": {"type": "object","properties": {"code": {"type": "integer","format": "int32"},"status": {"type": "string"}}},"LoginParams": {"type": "object","properties": {"username": {"type": "string"},"password": {"type": "string"},"autoLogin": {"type": "boolean"},"type": {"type": "string"}}},"ErrorResponse": {"required": ["errorCode"],"type": "object","properties": {"errorCode": {"type": "string","description": "业务约定的错误码"},"errorMessage": {"type": "string","description": "业务上的错误信息"},"success": {"type": "boolean","description": "业务上的请求是否成功"}}},"NoticeIconList": {"type": "object","properties": {"data": {"type": "array","items": {"$ref": "#/components/schemas/NoticeIconItem"}},"total": {"type": "integer","description": "列表的内容总数","format": "int32"},"success": {"type": "boolean"}}},"NoticeIconItemType": {"title": "NoticeIconItemType","description": "已读未读列表的枚举","type": "string","properties": {},"enum": ["notification", "message", "event"]},"NoticeIconItem": {"type": "object","properties": {"id": {"type": "string"},"extra": {"type": "string","format": "any"},"key": { "type": "string" },"read": {"type": "boolean"},"avatar": {"type": "string"},"title": {"type": "string"},"status": {"type": "string"},"datetime": {"type": "string","format": "date"},"description": {"type": "string"},"type": {"extensions": {"x-is-enum": true},"$ref": "#/components/schemas/NoticeIconItemType"}}}}}
}
proxy.ts
所有代理的配置。
/*** @name 代理的配置* @see 在生产环境 代理是无法生效的,所以这里没有生产环境的配置* -------------------------------* The agent cannot take effect in the production environment* so there is no configuration of the production environment* For details, please see* https://pro.ant.design/docs/deploy** @doc https://umijs.org/docs/guides/proxy*/
export default {// 如果需要自定义本地开发服务器 请取消注释按需调整// dev: {// // localhost:8000/api/** -> https://preview.pro.ant.design/api/**// '/api/': {// // 要代理的地址// target: 'https://preview.pro.ant.design',// // 配置了这个可以从 http 代理到 https// // 依赖 origin 的功能可能需要这个,比如 cookie// changeOrigin: true,// },// },/*** @name 详细的代理配置* @doc https://github.com/chimurai/http-proxy-middleware*/test: {// localhost:8000/api/** -> https://preview.pro.ant.design/api/**'/api/': {target: 'https://proapi.azurewebsites.net',changeOrigin: true,pathRewrite: { '^': '' },},},pre: {'/api/': {target: 'your pre url',changeOrigin: true,pathRewrite: { '^': '' },},},
};
routes.ts
路由表。
/*** @name umi 的路由配置* @description 只支持 path,component,routes,redirect,wrappers,name,icon 的配置* @param path path 只支持两种占位符配置,第一种是动态参数 :id 的形式,第二种是 * 通配符,通配符只能出现路由字符串的最后。* @param component 配置 location 和 path 匹配后用于渲染的 React 组件路径。可以是绝对路径,也可以是相对路径,如果是相对路径,会从 src/pages 开始找起。* @param routes 配置子路由,通常在需要为多个路径增加 layout 组件时使用。* @param redirect 配置路由跳转* @param wrappers 配置路由组件的包装组件,通过包装组件可以为当前的路由组件组合进更多的功能。 比如,可以用于路由级别的权限校验* @param name 配置路由的标题,默认读取国际化文件 menu.ts 中 menu.xxxx 的值,如配置 name 为 login,则读取 menu.ts 中 menu.login 的取值作为标题* @param icon 配置路由的图标,取值参考 https://ant.design/components/icon-cn, 注意去除风格后缀和大小写,如想要配置图标为 <StepBackwardOutlined /> 则取值应为 stepBackward 或 StepBackward,如想要配置图标为 <UserOutlined /> 则取值应为 user 或者 User* @doc https://umijs.org/docs/guides/routes*/
export default [{path: '/user',layout: false,routes: [{name: 'login',path: '/user/login',component: './User/Login',},],},{path: '/welcome',name: 'welcome',icon: 'smile',component: './Welcome',},{path: '/admin',name: 'admin',icon: 'crown',access: 'canAdmin',routes: [{path: '/admin',redirect: '/admin/sub-page',},{path: '/admin/sub-page',name: 'sub-page',component: './Admin',},],},{name: 'list.table-list',icon: 'table',path: '/list',component: './TableList',},{path: '/',redirect: '/welcome',},{path: '*',layout: false,component: './404',},
];