umi,中文可发音为乌米,是一个可插拔的企业级 react 应用框架
默认开启约定式路由
按需加载配置
更详细的介绍…
首先得有 node,并确保 node 版本是 8.10 或以上。
$ node -v
8.1x
使用npm 或者 yarn
yarn global add umi
npm -g install umi
// then 创建文件夹并进入文件夹
mkdir appname && cd appname
// 创建页面
umi g page index
umi g 是 umi generate 的别名,可用于快速生成 component、page、layout 等,并且可在插件里被扩展,比如 umi-plugin-dva 里扩展了 dva:model,然后就可以通过 umi g dva:model foo 快速 dva 的 model。
启动本地服务
umi dev
antd-admin
antd-admin 项目页面展示
├── /dist/ # 项目输出目录
├── /mock/ # 数据mock
├── /public/ # 公共文件,编译时copy至dist目录
├── /src/ # 项目源码目录
│ ├── /components/ # UI组件及UI相关方法
│ ├── /layouts/ # 全局组件
│ │ └── app.js # 页面入口
│ │ └── index.js # 入口文件
│ ├── /models/ # 数据模型
│ ├── /pages/ # 页面组件
│ │ └── document.ejs # html模版
│ ├── /services/ # 数据接口
│ ├── /themes/ # 项目样式
│ │ ├── default.less # 全局样式
│ │ └── vars.less # 全局样式变量
│ ├── /utils/ # 工具函数
│ │ ├── config.js # 项目常规配置
│ │ ├── menu.js # 菜单及面包屑配置
│ │ ├── config.js # 项目常规配置
│ │ ├── request.js # 异步请求函数(axios)
│ │ └── theme.js # 项目需要在js中使用到样式变量
├── package.json # 项目信息
├── .eslintrc # Eslint配置
└── .umirc.js # umi配置
└── .umirc.mock.js # mock配置
└── .theme.config.js # 主题less编译配置
components:组件(方法)为单位以文件夹保存,文件夹名组件首字母大写(如`DataTable`)
,方法首字母小写(如`layer`),文件夹内主文件与文件夹同名,多文件以`index.js`导出对象
(如`./src/components/Layout`)。
routes:页面为单位以文件夹保存,文件夹名首字母小写(特殊除外,如`UIElement`),文件夹
内主文件以`index.js`导出,多文件时可建立`components`文件夹
(如`./src/routes/dashboard`),
如果有子路由,依次按照路由层次建立文件夹(如`./src/routes/UIElement`)
alias: { // webpack 额外配置一些文件夹的快速访问
themes: resolve(__dirname, './src/themes'),
components: resolve(__dirname,"./src/components"),
utils: resolve(__dirname,"./src/utils"),
config: resolve(__dirname,"./src/utils/config"),
enums: resolve(__dirname,"./src/utils/enums"),
services: resolve(__dirname,"./src/services"),
models: resolve(__dirname,"./src/models"),
routes: resolve(__dirname,"./src/routes"),
},
类 next.js 的约定式路由,无需再维护一份冗余的路由配置,支持权限、动态路由、嵌套路由等等。
package.json中 npm依赖包版本前的符号的意义
推荐使用 https://www.npmjs.com/package/react-css-modules
使用stylename
webpack plugin
其中用户项目配置只有 .umirc.js 和 config/config.js 这两类,我习惯是用后者,不想再在根目录多出其他文件了。
// 内置插件
const builtInPlugins = [
'./plugins/commands/dev',
'./plugins/commands/build',
'./plugins/commands/test',
'./plugins/output-path',
'./plugins/global-js',
'./plugins/global-css',
'./plugins/mock',
'./plugins/proxy',
'./plugins/history',
'./plugins/afwebpack-config',
'./plugins/404', // 404 must after mock
];
用户的插件配置成
配置A
export default {
plugins: [
['umi-plugin-a', { foo: 'bar' }],
],
}
解析成
结果
{
id: 'umi-plugin-a',
apply: 'x',
opts: { foo: 'bar' },
}
register(hook, fn)
registerCommand(commandName, opts, fn)
registerMethod(name, { type, apply })
registerPlugin({ id, apply, opts })
applyPlugins(hook, { memo, args })
_applyPluginsAsync(hook, { memo, args })
onOptionChange(fn)
changePluginOption(id, newOpts)
addBabelRegister(files)
chainWebpackConfig(webpackConfig)
modifyAFWebpackOpts(afWebpackOpts => {})
_addConfig(config)
addPageWatcher(filePath)
addEntryImport({ source, specifier })
addEntryImportAhead({ source, specifier })
addEntryCode(code)
addEntryCodeAhead(code)
modifyEntryRender()
modifyEntryHistory()
addRouterImport({ source, specifier })
addRouterImportAhead({ source, specifier })
modifyRouterRootComponent()
onStart()
modifyRoutes(routes=> {})
onPatchRoute(route => {})
onGenerateFiles()
addHTMLMeta()
addHTMLLink()
addHTMLScript()
addHTMLHeadScript()
modifyDefaultConfig()