8

基于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 dev

umi包主要对外提供一些命令,如umi devumi buildumi inspectumi test

它通过实例化一个Service实例完成整个流程,new Service().run('dev', args);

Service的结构如下:
umiService.png

Service实例化之后,运行run方法,该方法有两步,第一步初始化,第二步运行对应的命令:
run

init方法对plugins中的各个plugin进行初始化:
initPlugin.png

initPlugin方法中通过Proxy对各个插件进行挂载更多的方法,dev命令注册的方法位于/umi-build-dev/src/plugins/commands/dev/index.js下。可以看出该命令最终通过af-webpack启动webpack运行起项目。

.umi目录是怎么生成的?

dev命令行中通过注册filesGenerator去生成.umi目录:
.umi

它通过chokidar对文件目录进行监控,当文件有更新时,会重新进行该目录的生成。

webpack配置如何封装?

Service是通过webpack-chain对webpack配置进行链式封装的:
webpack


simon_woo
2.1k 声望309 粉丝

我是一个爱生活,爱摄影,爱代码的前端工程师。我要成为这个宇宙最牛逼的大神。