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配置進行鏈式封裝的: