Miox帶你走進動態路由的世界——51信用卡前端團隊
寫在前面:
有的時候再做大型項目的時候,確實會被復雜的路由邏輯所煩惱,會經常遇到權限問題,路由跳轉回退邏輯問題。這幾天在網上看到了51信用卡團隊開源了一個Miox,可以有效的解決這些痛點,於是乎我就做了一些嘗試,確實很不錯,star增速也表明了業界對其的認可!由於自己能力有限,不能很好地解讀Miox,於是我就把Miox作者的文章給搬過來了,希望對大家有所幫著。(跟作者聊過之後,了解到作者團隊開發了2年多,沈澱了很深,後來選擇了開源,如果大家覺得好的話,可以去點一下star!)
github地址:GitHub: 51nb/Miox
文檔地址: https://51nb.github.io/miox-doc/
Miox帶你走進動態路由的世界
最近,我們團隊開源了一套沈澱了2年的前端SPA架構框架,主要是用來解決動態路由的問題。我們的思路來源於後端,采用中間件的設計模式來架構整個框架。我們的原則是讓大家快速開發一個SPA單頁應用,只關心業務邏輯,其他的行為都可以幫助處理掉。
其實我們的開源比較匆忙,從很多方面看還是有些不標準的,但是之後我們會嚴格按照標準的規範和流程走下去,給大家一份穩定的架構。對於現在開始關註我們團隊的小夥伴,我表示非常的感謝。有大家的支持,我們會做的更好。
Miox到底要解決什麽問題?
這個問題從我們設計的初衷來說,就是解決所有路由的問題。在業界,其實大家都普遍認可一對一的路由模式,從而生產出了很多路由體系,比如vue-router
react-router
。他們都是非常不錯的架構,從某種意義上來說,引領了前端路由的前進。很多小夥伴都是直接使用他們的全家桶來開發項目,也得到了很好的效果。
我不確定大家是否考慮過一個問題,當一個用戶從登陸頁面A登陸後進入B,再回到A頁面的情況。一對一的靜態路由其實理論上最終會將A頁面顯示為未登錄,這是完全正確的,但是邏輯上它應該是一個登錄的頁面。靜態路由無法區分環境變量對頁面選擇的影響,只能通過hook等手段來將頁面內容替換掉。理論上,我們借助後端的寫法應該是這樣的邏輯:
route.get(‘/a‘, ctx => { if (global.logined) { ctx.render(webveiwA); } else { ctx.render(webviewB); } })
我們需要根據周邊的環境變量去自動選擇該渲染哪個頁面,如此的邏輯才是我們想要的。所以我們會根據這樣的思路來設計動態路由。在nodejs
的世界中,這種模式已經非常常見,比如express-router
與koa-router
,都是采用這種設計思路來實現動態話的路由體系。我觀察了前端的發展,都沒有提出在前端實現這樣的邏輯。於是,我們便開始研究如何將這種思路架設在前端使用,來獲得更理想的邏輯體驗。
Miox從來都不是依賴任何MVX框架來實現
為什麽這麽說呢?原因非常簡單。在公司裏面,我們大概有90%的H5業務都是采用Miox來實現的。我們的技術棧其實是Vue,因為Miox對Vue的結合太過深入,所以自然有部分小夥伴認為Miox是基於Vue來開發的,也就是說Miox是依賴著Vue?其實不是,Miox並不依賴任何框架實現。我來舉個列子:
我們的電腦,如果換了一個顯卡,那麽必須要裝顯卡驅動。根據不同的顯卡驅動,表現也不同。如果我們將Vue當作一個顯卡,而Miox當作我們的電腦,那麽我們需要一份顯卡驅動來讓整臺電腦接受這塊顯卡。
所以我提出一個概念,就是渲染驅動的概念。Vue僅僅是我們Miox的一個渲染引擎,用來渲染頁面的,可以理解為模板。我們還需要一份驅動告訴Miox,來說明Vue的渲染是如何在Miox實現的。這部分可以從這裏看明白。當然,不僅僅是Vue,我們還能夠將React接入到Miox中。理論上,只要能提供對應的渲染驅動,都可以將任意的渲染引擎接入到Miox中來使用。自然的,大家的書寫都將會變成那種引擎的書寫方式。這就是我們的插拔式設計。在公司裏面使用的時候,我們不必在意使用何種渲染引擎,Miox都可以支持,同時幫您管理好整個路由體系。
基於中間件實現
在前端,如果我們能夠用中間件來攔截整個邏輯過程的話,對開發是相當有利的,不僅僅在代碼層面能夠提高可讀性,同時可以在具體業務層面提高效率。我們用後端路由邏輯來舉個例子:
當我們遇到一些API都是需要經過登錄驗證的時候,我們可以將
/authorize
的路由前綴都使用中間件統一處理。其他的都不走驗證邏輯。
const Authorize = require(‘./auth‘); const AuthorizeApi = require(‘./auth/routes‘); route.use( ‘/authorize‘, Authorize.connect(), // Authorize.connect是統一的驗證邏輯代碼 AuthorizeApi.routes(), AuthorizeApi.allowedMethods() );
如此當通過/authorize
的路由都需要經過Authorize.connect()
來驗證是否具有權限。這使得代碼非常簡潔易懂。
Miox的設計便是如此,通過這種中間件的架構,使得我們在前端獲得了統一攔截處理的能力。在實際生產中,我們很多地方都用到了中間件來處理統一的校驗邏輯,使得代碼維護性得到很大地提升。
那麽如果不使用呢?我們需要在進入頁面的時候,每個頁面中都要嵌入一段代碼來處理權限問題,不僅僅代碼量增加,而且對於之後的維護,可能會產生漏改的問題。
具體想了解中間件的小夥伴,我推薦去看下koa-router。
緩存頁面得到更好的渲染性能
說到緩存,這個話題過於龐大,對於Miox的緩存機制,我只能簡單介紹一下,有興趣的小夥伴可以看下源碼。
在開發過程中,特別是對於開發移動端頁面,我們需要保存前一個頁面滾動位置,那麽我們在切換到另一個頁面的時候是不能將前一個頁面銷毀的,原因是我們希望回到前一個頁面的時候還是停留在之前滾動的位置。那麽我們需要緩存這個頁面來確保位置的不改動。Miox模擬了history的部分API,同時增加了一層頁面堆棧。我們需要維護這層頁面堆棧來確保頁面的可溯性。每次我們通過一種算法來動態比較路由與頁面的關系,從而從這個堆棧中選出我們想要的緩存頁面。當然,沒有這個對應關系的時候,我們自然是要創建的。我們基於盡最大可能限度復用頁面的宗旨,來緩存這些頁面與路由的關系。
可能有人要問,如果緩存過多,對於頁面的切換會有性能上的影響吧?是的,過多的頁面緩存也是阻礙性能的關鍵。這裏我們進行了緩存個數的優化。在啟動miox服務的時候,我們有一個配置的參數max
,一般默認為一個,當然,大家也可以自己自由設置最大個數,來保障緩存的性能問題。
歷史遺留問題:history方向問題的解決方案
在History中,我們都承認無法判斷出當前瀏覽器行為的方向性,所以無法給出我們想要的方向來自動做頁面切換的效果。為了解決這個問題,我們搜集了業界的解決方案,采用sessionStorage
來模擬history堆棧,從而解決這個問題(新history的API中已經增加了history.index
動態屬性來告訴我們現在位於堆棧中的位置)。我們將此方案整合到了Miox中,並且對其加強,來告訴動畫引擎這次行為在瀏覽器中是如何表現的。自然,動畫引擎就能夠根據這個來自動切換頁面的動畫,達到自動處理的效果。
官方提供了一個簡單的模塊來支持動畫,當然小夥伴想要自定義動畫也是非常簡單的,具體見這裏。
獨立的頁面生命周期
在傳統的MVX框架中提供了組件的生命周期,我們在某種意義上也認為是頁面的生命周期,但是我們對比原生IOS的周期行為,還是有所欠缺的。比如說active
生命周期。這個是什麽意思呢?我來舉例說明:
當一個頁面被推入後臺,又被喚起的時候,我們根本不知道它是不是再一次被激活,我們只能知道頁面又一次被進入,第二次進入的概念是需要很多代碼來輔助完成的。而在傳統框架中,很難觸發再一次的
mounted
生命周期,因為頁面已經被mounted
過了。Miox提供了這樣的生命周期的定義。
// use vue.js export default Vue.extend({ mounted() { this.$on(‘webview:active‘, this.activeLife); }, methods: { activeLife() { console.log(‘我被喚起了‘); } } })
當然,我們也可以將這些生命周期直接拋到全局去,用於全局的監控。
app.on(‘webview:mounted‘, webview => { console.log(webview); })
對於前置的生命周期,我們同樣提供了以下的生命周期來輔助:
- webview:enter
- webview:leave
- webview:beforeEnter
- webview:beforeLeave
這些周期能夠讓你很好地掌控整個過程,對於自動埋點什麽的功能非常實用。
服務端渲染
目前主流的架構都支持了服務端渲染來增強SEO的能力,那麽對於Miox而言,也需要支持他們的服務端渲染。考慮到Miox自身會給渲染出來的內容包裹一些代碼,所以,我們需要自己實現SSR。當然,渲染引擎的SSR實現是交給自己來完成的。也就是說我們需要給他包裹一層SSR渲染。
Miox暫時支持Vue的SSR渲染,後續會逐步添加對於React的SSR渲染。還有比如百度的san.js
其實也可以接入進來實現SSR渲染。服務端渲染並不是太麻煩,如果大家能夠掌握Miox的運行原理的話。
最後
對於開源,我們團隊內部做了很多努力,也咨詢了很多大牛,希望能夠給大家創造出一份簡易開發的架構來幫助大家完成業務。目前,團隊後續計劃如下:
- 完善SSR的文檔
- 規範化Github上的git message
- 維護Github上的Issues和PR
- 單測和代碼覆蓋率增強
- 對路由架構更多思考來完善Miox
- 提供Pc端的演示demo
- 提供Miox實際開發場景下的開發代碼示例
希望大家看到這篇文章後可以支持我們,給我們多提供一些意見和建議,讓我們共同將Miox完善下去。喜歡的小夥伴,幫忙點個Star。
項目開源在 GitHub: 51nb/Miox
出處:掘金專欄-51信用卡前端團隊 https://juejin.im/post/5a0eee94f265da430702d8e0
Miox帶你走進動態路由的世界——51信用卡前端團隊