以上的組件代理插件實質上是用于做MF組件加載管理的chrome插件,可以控制基座應用加載的模塊是線上的還是本地。
代理方案如下
下面是具體實現:
generateRedirectUrl = (details: UrlDetailsType) => { if (details.url.includes(MICRO_ONLINE_LOAD_PATH)) { const redirectUrl = this.generateDefaultProxyUrl({ originUrl: details.url }) if (redirectUrl) { console.log('觸發代理', `${details.url}代理至${redirectUrl}`) this.checkMicroAppStatus({ originUrl: details.url, redirectUrl }) return { redirectUrl, } } } if (details.url.includes('t1-dev.dewu:98')) { console.log("details.url.includes('t1-dev.dewu:98')", details.url); const redirectUrl = this.generateOnlineUrlByLocal({ originUrl: details.url }) if (redirectUrl) { console.log('觸發代理', `${details.url}代理至${redirectUrl}`) this.checkMicroAppStatus({ originUrl: details.url, redirectUrl }) return { redirectUrl, } } } }
function getHost() { if (process.env.SOCKET_SERVER) { return new URL(process.env.SOCKET_SERVER); } return location;}function getSocketUrl() { let h = getHost(); let host = h.host; host = `localhost:${PORT}`; const isHttps = h.protocol === 'https:'; return `ws://${host}`;}function getPingUrl() { const h = getHost(); return `${h.protocol}//${h.host}/__umi_ping`;}
let pingTimer = null;let isFirstCompilation = true;let mostRecentCompilationHash = null;let hasCompileErrors = false;let hadRuntimeError = false;const pingUrl = getPingUrl();if (!window[`${APP_NAME}UmiEntry`]) { const socket = new WebSocket(getSocketUrl(), 'webpack-hmr'); socket.addEventListener('message', ({ data }) => __awaiter(void 0, void 0, void 0, function* () { data = JSON.parse(data); if (data.type === 'connected') { console.log(`[webpack] connected.`); // proxy(nginx, docker) hmr ws maybe caused timeout, // so send ping package let ws keep alive. pingTimer = setInterval(() => socket.send('ping'), 30000); } else { handleMessage(data).catch(console.error); } }), );}
前面的代理機制依賴于MF的遠程加載,模塊聯邦加載機制可參考「掘金」平臺中題目為“最詳細的Module Federation的實現原理講解” 這篇文章。基于模塊聯邦的微前端落地方案可以參考之前的一篇文章 基于Module Federation的模塊化跨棧方案探索。
本地與部署態基座應用通過MF方案加載子應用,同時部署態新增動態加載保證遠程組件的實時性,在加載入口文件處進行監控告警。
加載態依賴chrome插件做動態代理,實現本地與其他測試環境構建代碼的動態切換,同時子應用與部署態代碼建立websocket代碼更新鏈接,在子應用更新代碼時,實時刷新線上頁面。同時支持端口的動態配置,一鍵關閉。
以上介紹加載鏈路保證了構建部署提速與功能的完整,較好的解決了應用拆分功能不完備問題。本次架構優化將構建由15s減少至2.0s。業務需求部署速度由8min減少至2min。
應用拆分只是目的,要實現這個目標不僅僅要做拆分,對于商家后臺來說各個應用間的復用同等重要,由于是業務解耦,這意味著各應用間存在更多可復用的功能與模塊。
同時不僅是商家后臺的部分模塊也會在交易后臺使用,既要保證應用業務的解耦,同時要保證組件充分復用,大倉模式是目前最合適的方案。
由于商家后臺各個子應用由于同屬商家整條業務鏈路,存在眾多可共用的組件和模塊,而npm發布模式本身給業務組件與業務項目帶來了一定隔離性,同時因為各子應用業務上存在關聯,很多大型模塊需要被多個子應用引入,而這些大型模塊的迭代通常比較頻繁,同時需要對業務請求進行封裝。這里我們使用了基于大倉模式的源碼引入以達到代碼共用的目的。組件開發鏈路如下:
這里體現的是源碼引入的方式,在構建態進行通用模塊的打包構建,這一點目前能跑通的背景是商家后臺本身是一個完整的應用,現有的模式同樣是一個組件被多個模塊所使用,同時測試階段也是全量回歸。以下是大倉組件基礎鏈路:
之后會對該部分做詳細介紹。
以上主要講述了MF方案如何將本地結合線上開發,這里僅對微應用級別做了解耦,基于MF的模塊化實現,由于remoteMicro實質上是創建了一個引用路徑到require函數的映射然后代理至本地,那么對于不同模塊,在能力上是具備模塊化代理的能力的,基于目前MF按需構建(僅構建暴露出去的組件模塊)的規則,我們可以對某個模塊的映射對象里的xxx.async.js做代理。這樣就可以實現頁面粒度的按需構建,在部署構建提速上有很大潛力。
本篇文章主要介紹了如何對商家巨石應用做拆分,包括拆分方案的介紹,如何同時保證單個構建與功能完整性,并且針對微應用代理加載進行了進一步探索,接著介紹了大倉模式下需要遵循的規范以及未來的規劃。大倉模式目前在前端平臺已經持續不斷地完善,將來應該會針對此模式做更詳細的介紹,在拆分這件事情上,對于構建本身或許能被更加細粒度化,構建文件的代理本質上減少了代碼的構建量,目前是通過人為控制的方式,此次驗證了模塊聯邦支持可代理與動態更改expose。基于這兩個特性,是否能將構建做到更加局部化,這可能會成為構建優化的方向。應用拆分一方面提升了開發人員的開發與部署效率,同時也對業務迭代流程做了業務解耦,明確了責任邊界,更有利于后臺應用的開發需求管理,降低需求代碼維護成本。
本文鏈接:http://www.www897cc.com/showinfo-26-6162-0.html基于模塊聯邦與大倉模式的商家巨石應用拆分實踐
聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。郵件:2376512515@qq.com
上一篇: 轉轉游戲的賬號訂單流程重構之路
下一篇: 如何編寫技術文檔?