Umi是阿里的一款基於React的企業級應用框架。本文將會從3個方面介紹下基於Umi的開發方案:css
umi是一款可插拔的企業級react應用框架,支持約定式路由以及各類進階路由功能,並以此進行功能擴展,擁有完善的插件體系,覆蓋從源碼到構建產物的每一個生命週期,支持各類功能擴展和業務需求。react
它有如下特性:webpack
一個umi工程的生命週期以下,它包含源碼到上線的整個流程,umi 首先會加載用戶的配置和插件,而後基於配置或者目錄,生成一份路由配置,再基於此路由配置,把 JS/CSS 源碼和 HTML 完整地串聯起來。用戶配置的參數和插件會影響流程裏的每一個環節。git
建立一個umi項目可經過2種方式,手工建立和腳手架建立。github
第一步,建立相關文件夾:web
mkdir umi_app && cd umi_app
npm init
mkdir pages
複製代碼
第二步,增長npm script:typescript
"scripts": {
"start": "umi dev",
"build": "umi build」, } 複製代碼
第三步,增長依賴:express
"devDependencies": {
"umi": "^2.6.3"
}
複製代碼
第四步,在pages目錄下,增長新模塊。 最後,使用npm run start
便可運行該項目。npm
umi提供了腳手架工具create-umi來加快umi工程的建立。json
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配置進行鏈式封裝的: