Umi是阿里的一款基于React的企业级应用框架。本文将会从3个方面介绍下基于Umi的开发方案:css
umi是如何实现的?react
umi是一款可插拔的企业级react应用框架,支持约定式路由以及各类进阶路由功能,并以此进行功能扩展,拥有完善的插件体系,覆盖从源码到构建产物的每一个生命周期,支持各类功能扩展和业务需求。webpack
它有如下特性:git
一个umi工程的生命周期以下,它包含源码到上线的整个流程,umi 首先会加载用户的配置和插件,而后基于配置或者目录,生成一份路由配置,再基于此路由配置,把 JS/CSS 源码和 HTML 完整地串联起来。用户配置的参数和插件会影响流程里的每一个环节。github
建立一个umi项目可经过2种方式,手工建立和脚手架建立。web
第一步,建立相关文件夹:typescript
mkdir umi_app && cd umi_app npm init mkdir pages
第二步,增长npm script:express
"scripts": { "start": "umi dev", "build": "umi build”, }
第三步,增长依赖:npm
"devDependencies": { "umi": "^2.6.3" }
第四步,在pages目录下,增长新模块。
最后,使用npm run start
便可运行该项目。json
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运行起项目。
dev命令行中经过注册filesGenerator去生成.umi目录:
它经过chokidar
对文件目录进行监控,当文件有更新时,会从新进行该目录的生成。
Service是经过webpack-chain
对webpack配置进行链式封装的: