自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

基于模塊聯(lián)邦與大倉(cāng)模式的商家巨石應(yīng)用拆分實(shí)踐

開發(fā)
微前端是目前解決應(yīng)用拆分的主要解決方案,但是由于其隔離性的機(jī)制使得各個(gè)子應(yīng)用間完全隔離,使得用戶在開發(fā)子應(yīng)用時(shí)無(wú)法訪問(wèn)其他子應(yīng)用頁(yè)面,這對(duì)于各子應(yīng)用存在關(guān)聯(lián)關(guān)系需要同時(shí)訪問(wèn)開發(fā)的場(chǎng)景開發(fā)效率較低...

一、背景

商家后臺(tái)前端代碼目前代碼量達(dá)到十萬(wàn)級(jí),每個(gè)迭代團(tuán)隊(duì)需要在同一倉(cāng)庫(kù)中迭代幾十個(gè)需求,在日漸龐大的巨石應(yīng)用下如此活躍的迭代,開發(fā)效率與構(gòu)建效率上給我們帶來(lái)了一些挑戰(zhàn),我們需要優(yōu)化以下幾點(diǎn):

  1. 代碼構(gòu)建體量大,隨著時(shí)間推移,構(gòu)建速度的優(yōu)化空間較少。
  2. 巨石應(yīng)用下各個(gè)業(yè)務(wù)模塊沒(méi)有做物理拆分,管理與維護(hù)難度提升。
  3. 應(yīng)用粒度較粗,在發(fā)布節(jié)點(diǎn)上需要對(duì)應(yīng)用做進(jìn)一步拆分以優(yōu)化發(fā)布粒度。
  4. 巨石應(yīng)用下,組件與業(yè)務(wù)的關(guān)系需要梳理,避免出現(xiàn)重復(fù)開發(fā)的情況。

微前端是目前解決應(yīng)用拆分的主要解決方案,但是由于其隔離性的機(jī)制使得各個(gè)子應(yīng)用間完全隔離,使得用戶在開發(fā)子應(yīng)用時(shí)無(wú)法訪問(wèn)其他子應(yīng)用頁(yè)面,這對(duì)于各子應(yīng)用存在關(guān)聯(lián)關(guān)系需要同時(shí)訪問(wèn)開發(fā)的場(chǎng)景開發(fā)效率較低,并且目前市面上已經(jīng)完全封裝的主流微前端框架對(duì)我們來(lái)說(shuō)是黑盒,無(wú)法做到高度自定義,無(wú)法滿足特定拆分需求,因此我們決定采用模塊聯(lián)邦與大倉(cāng)模式結(jié)合的方式解決以上問(wèn)題。

二、目標(biāo)

提升構(gòu)建與維護(hù)效率

將巨石應(yīng)用進(jìn)行拆分,獨(dú)立開發(fā)與部署、提升構(gòu)建部署效率與代碼維護(hù)效率。

雖是單個(gè)子應(yīng)用開發(fā),但可全量訪問(wèn)巨石應(yīng)用模塊

由于商家內(nèi)部各應(yīng)用間在業(yè)務(wù)上存在上下游的關(guān)系,我們?cè)陂_發(fā)D子應(yīng)用時(shí),需要在其上游的C、B子應(yīng)用中進(jìn)行相關(guān)配置,它們之間是強(qiáng)綁定的關(guān)系,結(jié)論就是:需要在本地開發(fā)時(shí),能夠同時(shí)使用其他子應(yīng)用的頁(yè)面模塊的功能。

三、技術(shù)方案

以上提到的提升構(gòu)建與維護(hù)效率,目前微前端與MF方案都是支持的,關(guān)鍵點(diǎn)在于如何在本地開發(fā)能夠訪問(wèn)到平臺(tái)的全量功能。本地代碼已經(jīng)有了,啟動(dòng)本地進(jìn)程即可,那么,其他子應(yīng)用如何訪問(wèn)?

微應(yīng)用代理

如果是從本地再啟動(dòng)其他應(yīng)用,這其實(shí)就背離了應(yīng)用拆分的初衷,同時(shí)也降低了本地開發(fā)的效率,同時(shí)隨著子應(yīng)用越來(lái)越多,本地進(jìn)程也會(huì)越來(lái)越多,這可能會(huì)大大影響本地開發(fā)效率。看來(lái)本地啟動(dòng)行不通,那么從哪里訪問(wèn)呢?對(duì)了,線上不是可以訪問(wèn)到其他模塊嗎?但是怎么將本地開發(fā)與線上的模塊結(jié)合呢?由于目前商家后臺(tái)使用了MF方式在路由層或vue文件內(nèi)遠(yuǎn)程引入MF模塊,那么是否可以通過(guò)MF模塊轉(zhuǎn)發(fā)的方式將遠(yuǎn)程組件代理至本地組件呢?

以上的組件代理插件實(shí)質(zhì)上是用于做MF組件加載管理的chrome插件,可以控制基座應(yīng)用加載的模塊是線上的還是本地。

代理方案如下

  • 用戶首次進(jìn)入線上測(cè)試環(huán)境,會(huì)加載遠(yuǎn)程應(yīng)用入口文件,代理插件會(huì)將入口文件根據(jù)用戶配置轉(zhuǎn)發(fā)至對(duì)應(yīng)的本地地址。
  • 進(jìn)入路由訪問(wèn),由于上一步對(duì)遠(yuǎn)程應(yīng)用入口做了代理,加載的模塊被代理至本地,這樣用戶就可以在線上訪問(wèn)到本地頁(yè)面,實(shí)現(xiàn)本地開發(fā)。
  • 在線上基座應(yīng)用與本地應(yīng)用間建立websocket鏈接,本地應(yīng)用代碼更改后通知線上基座應(yīng)用刷新頁(yè)面。

下面是具體實(shí)現(xiàn):

generateRedirectUrl = (details: UrlDetailsType) => {
    if (details.url.includes(MICRO_ONLINE_LOAD_PATH)) {
      const redirectUrl = this.generateDefaultProxyUrl({ originUrl: details.url })
      if (redirectUrl) {
        console.log('觸發(fā)代理', `${details.url}代理至${redirectUrl}`)
        this.checkMicroAppStatus({ originUrl: details.url, redirectUrl })

        return {
          redirectUrl,
        }
      }
    }
    if (details.url.includes('t1-dev.dewu.net:98')) {
      console.log("details.url.includes('t1-dev.dewu.net:98')", details.url);
      const redirectUrl = this.generateOnlineUrlByLocal({ originUrl: details.url })
      if (redirectUrl) {
        console.log('觸發(fā)代理', `${details.url}代理至${redirectUrl}`)
        this.checkMicroAppStatus({ originUrl: details.url, redirectUrl })
        return {
          redirectUrl,
        }
      }
    }
  }
  • 文件內(nèi)容代理為本地文件后,此時(shí)對(duì)應(yīng)的模塊加載path還是會(huì)加載線上路由,這里同樣需要做內(nèi)容代理。
  • 由于是基于線上測(cè)試環(huán)境開發(fā),本地開發(fā)的頁(yè)面不僅需要在線上展示,并且本地代碼更新后需要觸發(fā)線上頁(yè)面更新,這是必不可少的步驟,我們基于websocket將本地與線上進(jìn)行連接。
  • 不同子應(yīng)用動(dòng)態(tài)設(shè)置socketUrl與PingUrl。
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`;
}
  • 建立websocket連接,并定時(shí)觸發(fā)連接檢測(cè)。
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);
      }
    }),
  );
}
  • 本地需求開發(fā)共享部署態(tài)代碼的store與路由跳轉(zhuǎn)。
  • 需求開發(fā)完成后進(jìn)行單個(gè)應(yīng)用部署,由于是本地代理,不影響測(cè)試訪問(wèn)。

基于模塊聯(lián)邦

前面的代理機(jī)制依賴于MF的遠(yuǎn)程加載,模塊聯(lián)邦加載機(jī)制可參考「掘金」平臺(tái)中題目為“最詳細(xì)的Module Federation的實(shí)現(xiàn)原理講解” 這篇文章?;谀K聯(lián)邦的微前端落地方案可以參考之前的一篇文章 基于Module Federation的模塊化跨棧方案探索。

本地與部署態(tài)基座應(yīng)用通過(guò)MF方案加載子應(yīng)用,同時(shí)部署態(tài)新增動(dòng)態(tài)加載保證遠(yuǎn)程組件的實(shí)時(shí)性,在加載入口文件處進(jìn)行監(jiān)控告警。

基座應(yīng)用為部署態(tài),在進(jìn)行MF加載時(shí),通過(guò)chrome插件動(dòng)態(tài)控制加載子文件路徑,開發(fā)態(tài)子應(yīng)用共享部署態(tài)代碼的store,路由注冊(cè)等基礎(chǔ)配置。

加載態(tài)依賴chrome插件做動(dòng)態(tài)代理,實(shí)現(xiàn)本地與其他測(cè)試環(huán)境構(gòu)建代碼的動(dòng)態(tài)切換,同時(shí)子應(yīng)用與部署態(tài)代碼建立websocket代碼更新鏈接,在子應(yīng)用更新代碼時(shí),實(shí)時(shí)刷新線上頁(yè)面。同時(shí)支持端口的動(dòng)態(tài)配置,一鍵關(guān)閉。

效果

以上介紹加載鏈路保證了構(gòu)建部署提速與功能的完整,較好的解決了應(yīng)用拆分功能不完備問(wèn)題。本次架構(gòu)優(yōu)化將構(gòu)建由15s減少至2.0s。業(yè)務(wù)需求部署速度由8min減少至2min。

四、應(yīng)用拆分

大倉(cāng)模式

應(yīng)用拆分只是目的,要實(shí)現(xiàn)這個(gè)目標(biāo)不僅僅要做拆分,對(duì)于商家后臺(tái)來(lái)說(shuō)各個(gè)應(yīng)用間的復(fù)用同等重要,由于是業(yè)務(wù)解耦,這意味著各應(yīng)用間存在更多可復(fù)用的功能與模塊。

同時(shí)不僅是商家后臺(tái)的部分模塊也會(huì)在交易后臺(tái)使用,既要保證應(yīng)用業(yè)務(wù)的解耦,同時(shí)要保證組件充分復(fù)用,大倉(cāng)模式是目前最合適的方案。

大倉(cāng)模塊化共享

由于商家后臺(tái)各個(gè)子應(yīng)用由于同屬商家整條業(yè)務(wù)鏈路,存在眾多可共用的組件和模塊,而npm發(fā)布模式本身給業(yè)務(wù)組件與業(yè)務(wù)項(xiàng)目帶來(lái)了一定隔離性,同時(shí)因?yàn)楦髯討?yīng)用業(yè)務(wù)上存在關(guān)聯(lián),很多大型模塊需要被多個(gè)子應(yīng)用引入,而這些大型模塊的迭代通常比較頻繁,同時(shí)需要對(duì)業(yè)務(wù)請(qǐng)求進(jìn)行封裝。這里我們使用了基于大倉(cāng)模式的源碼引入以達(dá)到代碼共用的目的。組件開發(fā)鏈路如下:

這里體現(xiàn)的是源碼引入的方式,在構(gòu)建態(tài)進(jìn)行通用模塊的打包構(gòu)建,這一點(diǎn)目前能跑通的背景是商家后臺(tái)本身是一個(gè)完整的應(yīng)用,現(xiàn)有的模式同樣是一個(gè)組件被多個(gè)模塊所使用,同時(shí)測(cè)試階段也是全量回歸。以下是大倉(cāng)組件基礎(chǔ)鏈路:

  1. 組件構(gòu)建發(fā)布使用標(biāo)準(zhǔn)的cli規(guī)范。
  2. 在提交MR節(jié)點(diǎn)與發(fā)布節(jié)點(diǎn)新增自動(dòng)化卡口。
  3. 通過(guò)依賴分析自動(dòng)化檢測(cè)單測(cè)運(yùn)行范圍。
  4. 組件發(fā)布時(shí)發(fā)布通知,提醒組件使用者,并運(yùn)行業(yè)務(wù)單測(cè)。

之后會(huì)對(duì)該部分做詳細(xì)介紹。

五、總結(jié)與思考

單應(yīng)用構(gòu)建->單頁(yè)面構(gòu)建?

以上主要講述了MF方案如何將本地結(jié)合線上開發(fā),這里僅對(duì)微應(yīng)用級(jí)別做了解耦,基于MF的模塊化實(shí)現(xiàn),由于remoteMicro實(shí)質(zhì)上是創(chuàng)建了一個(gè)引用路徑到require函數(shù)的映射然后代理至本地,那么對(duì)于不同模塊,在能力上是具備模塊化代理的能力的,基于目前MF按需構(gòu)建(僅構(gòu)建暴露出去的組件模塊)的規(guī)則,我們可以對(duì)某個(gè)模塊的映射對(duì)象里的xxx.async.js做代理。這樣就可以實(shí)現(xiàn)頁(yè)面粒度的按需構(gòu)建,在部署構(gòu)建提速上有很大潛力。

本篇文章主要介紹了如何對(duì)商家巨石應(yīng)用做拆分,包括拆分方案的介紹,如何同時(shí)保證單個(gè)構(gòu)建與功能完整性,并且針對(duì)微應(yīng)用代理加載進(jìn)行了進(jìn)一步探索,接著介紹了大倉(cāng)模式下需要遵循的規(guī)范以及未來(lái)的規(guī)劃。大倉(cāng)模式目前在前端平臺(tái)已經(jīng)持續(xù)不斷地完善,將來(lái)應(yīng)該會(huì)針對(duì)此模式做更詳細(xì)的介紹,在拆分這件事情上,對(duì)于構(gòu)建本身或許能被更加細(xì)粒度化,構(gòu)建文件的代理本質(zhì)上減少了代碼的構(gòu)建量,目前是通過(guò)人為控制的方式,此次驗(yàn)證了模塊聯(lián)邦支持可代理與動(dòng)態(tài)更改expose。基于這兩個(gè)特性,是否能將構(gòu)建做到更加局部化,這可能會(huì)成為構(gòu)建優(yōu)化的方向。應(yīng)用拆分一方面提升了開發(fā)人員的開發(fā)與部署效率,同時(shí)也對(duì)業(yè)務(wù)迭代流程做了業(yè)務(wù)解耦,明確了責(zé)任邊界,更有利于后臺(tái)應(yīng)用的開發(fā)需求管理,降低需求代碼維護(hù)成本。

責(zé)任編輯:龐桂玉 來(lái)源: 得物技術(shù)
相關(guān)推薦

2024-07-11 11:31:17

2021-04-27 19:20:54

微應(yīng)用模塊聯(lián)邦

2022-05-13 12:34:16

美團(tuán)開發(fā)實(shí)踐

2023-12-07 07:02:00

大倉(cāng)權(quán)限設(shè)計(jì)

2020-09-15 13:55:22

密碼技術(shù)車聯(lián)網(wǎng)

2025-01-07 14:42:09

2024-05-07 08:31:09

SpringFlowable業(yè)務(wù)流程

2015-03-10 18:13:08

2022-06-03 09:30:31

店鋪W3C體系渲染

2014-05-05 11:41:09

云儲(chǔ)存谷歌

2023-12-06 13:18:00

物聯(lián)網(wǎng)

2022-12-23 19:22:47

前端單測(cè)

2023-11-27 18:38:57

得物商家測(cè)試

2021-12-08 10:35:04

開源監(jiān)控Zabbix

2017-05-18 11:43:41

Android模塊化軟件

2022-03-22 22:05:39

區(qū)塊鏈支付模式

2009-01-03 14:57:19

ibmdwLotusWeb2.0

2023-03-10 10:29:19

前端邏輯拆分

2023-11-07 12:09:44

TopicKafka
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)