1. 程式人生 > >Miox帶你走進動態路由的世界——51信用卡前端團隊

Miox帶你走進動態路由的世界——51信用卡前端團隊

完成 算法 這樣的 def pac 搜集 https 高效 整合

寫在前面:

有的時候再做大型項目的時候,確實會被復雜的路由邏輯所煩惱,會經常遇到權限問題,路由跳轉回退邏輯問題。這幾天在網上看到了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-routerkoa-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信用卡前端團隊