基于Umi的开发方案
Umi是阿里的一款基于React的企业级应用框架。本文将会从3个方面介绍下基于Umi的开发方案:
- umi是什么?
- 怎么使用umi?
-
umi是如何实现的?
umi是什么
umi是一款可插拔的企业级react应用框架,支持约定式路由以及各种进阶路由功能,并以此进行功能扩展,拥有完善的插件体系,覆盖从源码到构建产物的每个生命周期,支持各种功能扩展和业务需求。
它有以下特性:
- 开箱即用,内置react,react-router等
- 约定式路由,同时支持可配置路由
- 完善的插件体系
- 支持typescript
- 支持dva数据方案
一个umi工程的生命周期如下,它包含源码到上线的整个流程,umi 首先会加载用户的配置和插件,然后基于配置或者目录,生成一份路由配置,再基于此路由配置,把 JS/CSS 源码和 HTML 完整地串联起来。用户配置的参数和插件会影响流程里的每个环节。
使用
创建一个umi项目
创建一个umi项目可通过2种方式,手工创建和脚手架创建。
手工创建
第一步,创建相关文件夹:
mkdir umi_app && cd umi_app
npm init
mkdir pages
第二步,增加npm script:
"scripts": {
"start": "umi dev",
"build": "umi build”,
}
第三步,增加依赖:
"devDependencies": {
"umi": "^2.6.3"
}
第四步,在pages目录下,增加新模块。
最后,使用npm run start
即可运行该项目。
脚手架创建
umi提供了脚手架工具create-umi来加快umi工程的创建。
mkdir umi_app && cd umi_app
create-umi
npm i
最后,使用npm run start
即可运行项目,在localhost:8000访问该项目。
业务开发
创建出来的项目目录结构如下:
.
├── dist/ // 默认的 build 输出目录
├── mock/ // mock 文件所在目录,基于 express
├── config/
├── config.js // umi 配置,同 .umirc.js,二选一
└── src/ // 源码目录,可选
├── layouts/index.js // 全局布局
├── pages/ // 页面目录,里面的文件即路由
├── .umi/ // dev 临时目录,需添加到 .gitignore
├── .umi-production/ // build 临时目录,会自动删除
├── document.ejs // HTML 模板
├── 404.js // 404 页面
├── page1.js // 页面 1,任意命名,导出 react 组件
├── page1.test.js // 用例文件,umi test 会匹配所有 .test.js 和 .e2e.js 结尾的文件
└── page2.js // 页面 2,任意命名
├── global.css // 约定的全局样式文件,自动引入,也可以用 global.less
├── global.js // 可以在这里加入 polyfill
├── app.js // 运行时配置文件
├── .umirc.js // umi 配置,同 config/config.js,二选一
├── .env // 环境变量
└── package.json
.umi目录是umi dev生成的临时目录,默认包含 umi.js 和 router.js。.umi-production是在umi build生成的临时目录。
通过命令行umi g page users
生成users页面,在localhost:8000/users即可访问该页面。
同时,也可以使用dva作为状态管理工具配合umi进行开发,可参考umi + dva,完成用户管理的 CURD 应用。
使用插件
基于umi的插件机制,你可以获得扩展项目的编译时和运行时的能力。通过插件支持的功能也会变得更强大,我们针对功能的需要可以去使用修改代码打包配置,修改启动代码,约定目录结构,修改 HTML 等更丰富接口。插件可以是一个 npm 包,也可以是路径直接引向一个 JS 的模块。用户通过配置 plugins 来使用插件。如下所示:
// .umirc.js
export default {
plugins: [
[
'umi-plugin-dva',
{
immer: true,
},
],
[
'./src/plugins/customPlugin.js',
{
// plugin config
},
],
],
};
如何实现
umi的插件机制非常优秀,我们通过umi dev
进行分析,来窥探下umi的插件机制是如何实现的。umi的源代码地址:umi github。通过源代码看出,它是一个lerna的多packages项目,源代码在packages
目录下。
umi dev
的整个流程如下:
umi包主要对外提供一些命令,如umi dev
,umi build
,umi inspect
,umi test
。
它通过实例化一个Service实例完成整个流程,new Service().run('dev', args);
。
Service的结构如下:
Service实例化之后,运行run
方法,该方法有两步,第一步初始化,第二步运行对应的命令:
init方法对plugins中的各个plugin进行初始化:
initPlugin
方法中通过Proxy对各个插件进行挂载更多的方法,dev命令注册的方法位于/umi-build-dev/src/plugins/commands/dev/index.js
下。可以看出该命令最终通过af-webpack
启动webpack运行起项目。
.umi目录是怎么生成的?
dev命令行中通过注册filesGenerator去生成.umi目录:
它通过chokidar
对文件目录进行监控,当文件有更新时,会重新进行该目录的生成。
webpack配置如何封装?
Service是通过webpack-chain
对webpack配置进行链式封装的:
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。