真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

微前端框架導(dǎo)入加載子應(yīng)用的方法是什么

本篇內(nèi)容主要講解“微前端框架導(dǎo)入加載子應(yīng)用的方法是什么”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學(xué)習(xí)“微前端框架導(dǎo)入加載子應(yīng)用的方法是什么”吧!

創(chuàng)新互聯(lián)公司服務(wù)項目包括新晃網(wǎng)站建設(shè)、新晃網(wǎng)站制作、新晃網(wǎng)頁制作以及新晃網(wǎng)絡(luò)營銷策劃等。多年來,我們專注于互聯(lián)網(wǎng)行業(yè),利用自身積累的技術(shù)優(yōu)勢、行業(yè)經(jīng)驗、深度合作伙伴關(guān)系等,向廣大中小型企業(yè)、政府機構(gòu)等提供互聯(lián)網(wǎng)行業(yè)的解決方案,新晃網(wǎng)站推廣取得了明顯的社會效益與經(jīng)濟效益。目前,我們服務(wù)的客戶以成都為中心已經(jīng)輻射到新晃省份的部分城市,未來相信會繼續(xù)擴大服務(wù)區(qū)域并繼續(xù)獲得客戶的支持與信任!

下面代碼,我指定的entry,就是子應(yīng)用的訪問入口地址

微前端框架導(dǎo)入加載子應(yīng)用的方法是什么

微前端到底是怎么回事呢?  我畫了一張圖

微前端框架導(dǎo)入加載子應(yīng)用的方法是什么

我們今天不談其他的實現(xiàn)技術(shù)細(xì)節(jié),坑點,就談?wù)w架構(gòu),這張圖就能完全解釋清楚

那么registerMicroApps,到底做了什么呢?

微前端框架導(dǎo)入加載子應(yīng)用的方法是什么

源碼解析下,只看重要部分今天:

lifeCycles是我們自己傳入的生命周期函數(shù)(這里先不解釋),跟react這種框架一樣,微前端針對每個子應(yīng)用,也封裝了一些生命周期,如果你是小白,那我就用最簡單的話告訴你,生命周期鉤子,其實在框架源碼就是一個函數(shù)編寫調(diào)用順序而已(有的分異步和同步)

apps就是我們傳入的數(shù)組,子應(yīng)用集合

代碼里做了一些防重復(fù)注冊、數(shù)據(jù)處理等

看源碼,不要全部都看,那樣很費時間,而且你也得不到利益最大化,只看最精髓、重要部分

無論上面做了上面子應(yīng)用去重、數(shù)據(jù)處理,我只要盯著每個子應(yīng)用,即app這個對象即可

看到了loadApp這個方法,我們可以大概猜測到,是通過這個方法加載

下面__rest是對數(shù)據(jù)進(jìn)行處理

微前端框架導(dǎo)入加載子應(yīng)用的方法是什么

loadApp這個函數(shù)有大概300行,挑最重點地方看

微前端框架導(dǎo)入加載子應(yīng)用的方法是什么

registerApplication是single-spa的方法,我們這里通過loadApp這個方法,對數(shù)據(jù)進(jìn)行處理

微前端框架導(dǎo)入加載子應(yīng)用的方法是什么

上面這個函數(shù),應(yīng)該是整個微前端框架最復(fù)雜的地方,它最終會返回一個函數(shù),當(dāng)成函數(shù)傳遞給single-spa這個庫的registerApplication方法使用

它的內(nèi)部是switch case邏輯,然后返回一個數(shù)組

這是一個邏輯判斷

case 0:            entry = app.entry, appappName = app.name;            _b = configuration.singular, singular = _b === void 0 ? false : _b, _c = configuration.sandbox, sandbox = _c === void 0 ? true : _c, importEntryOpts = __rest(configuration, ["singular", "sandbox"]);  return [4  /*yield*/            , importEntry(entry, importEntryOpts)];

重點來了

會通過importEntry 去加載entry(子應(yīng)用地址)

微前端框架導(dǎo)入加載子應(yīng)用的方法是什么 

上面代碼里最重要的,如果我們entry傳入字符串,那么就會使用這個函數(shù)去加載HTML內(nèi)容(其實微前端的所有子應(yīng)用加載,都是把dom節(jié)點加載渲染到基座的index.html文件中的一個div標(biāo)簽內(nèi))

微前端框架導(dǎo)入加載子應(yīng)用的方法是什么

importHTML這個函數(shù),就是我們今晚最重要的一個點

傳入url地址,發(fā)起fetch請求(此時由于域名或者端口不一樣,會出現(xiàn)跨域,所有子應(yīng)用的熱更新開發(fā)模式下,webpack配置要做以下處理,部署也要考慮這個問題)

微前端框架導(dǎo)入加載子應(yīng)用的方法是什么

整個importHTML函數(shù)好像很長很長,但是我們就看最重要的地方,一個框架(庫),流程線很長+版本迭代原因,需要兼容老的版本,所以很多源碼對于我們其實是無用的

微前端框架導(dǎo)入加載子應(yīng)用的方法是什么

整個函數(shù),最后返回了一個對象,這里很明顯,通過fetch請求,獲取了對應(yīng)子應(yīng)用entry入口的資源文件后,轉(zhuǎn)換成了字符串

這里processTpl其實就是對這個子應(yīng)用的dom模版(字符串格式)進(jìn)行一個數(shù)據(jù)拼裝,其實也不是很復(fù)雜,由于時間關(guān)系,可以自己看看過程,重點看結(jié)果

這里的思想,是redux的中間件源碼思想,將數(shù)據(jù)進(jìn)行了一層包裝,高可用使用

function processTpl(tpl, baseURI) {  var scripts = [];  var styles = [];  var entry = null;  var template = tpl  /*    remove html comment first    */    .replace(HTML_COMMENT_REGEX, '').replace(LINK_TAG_REGEX, function (match) {  /*      change the css link      */  var styleType = !!match.match(STYLE_TYPE_REGEX);  if (styleType) {  var styleHref = match.match(STYLE_HREF_REGEX);  var styleIgnore = match.match(LINK_IGNORE_REGEX);  if (styleHref) {  var href = styleHref && styleHref[2];  var newHref = href;  if (href && !hasProtocol(href)) {            newHref = getEntirePath(href, baseURI);          }  if (styleIgnore) {  return genIgnoreAssetReplaceSymbol(newHref);          }          styles.push(newHref);  return genLinkReplaceSymbol(newHref);        }      }  var preloadOrPrefetchType = match.match(LINK_PRELOAD_OR_PREFETCH_REGEX) && match.match(LINK_HREF_REGEX);  if (preloadOrPrefetchType) {  var _match$matchmatch = match.match(LINK_HREF_REGEX),            _match$match3 = (0, _slicedToArray2["default"])(_match$match, 3),            linkHref = _match$match3[2];  return genLinkReplaceSymbol(linkHref, true);      }  return match;    }).replace(STYLE_TAG_REGEX, function (match) {  if (STYLE_IGNORE_REGEX.test(match)) {  return genIgnoreAssetReplaceSymbol('style file');      }  return match;    }).replace(ALL_SCRIPT_REGEX, function (match) {  var scriptIgnore = match.match(SCRIPT_IGNORE_REGEX); // in order to keep the exec order of all javascripts  // if it is a external script  if (SCRIPT_TAG_REGEX.test(match) && match.match(SCRIPT_SRC_REGEX)) {  /*       collect scripts and replace the ref        */  var matchmatchedScriptEntry = match.match(SCRIPT_ENTRY_REGEX);  var matchmatchedScriptSrcMatch = match.match(SCRIPT_SRC_REGEX);  var matchedScriptSrc = matchedScriptSrcMatch && matchedScriptSrcMatch[2];  if (entry && matchedScriptEntry) {  throw new SyntaxError('You should not set multiply entry script!');        } else {  // append the domain while the script not have an protocol prefix  if (matchedScriptSrc && !hasProtocol(matchedScriptSrc)) {            matchedScriptSrc = getEntirePath(matchedScriptSrc, baseURI);          }          entryentry = entry || matchedScriptEntry && matchedScriptSrc;        }  if (scriptIgnore) {  return genIgnoreAssetReplaceSymbol(matchedScriptSrc || 'js file');        }  if (matchedScriptSrc) {  var asyncScript = !!match.match(SCRIPT_ASYNC_REGEX);          scripts.push(asyncScript ? {            async: true,            src: matchedScriptSrc          } : matchedScriptSrc);  return genScriptReplaceSymbol(matchedScriptSrc, asyncScript);        }  return match;      } else {  if (scriptIgnore) {  return genIgnoreAssetReplaceSymbol('js file');        } // if it is an inline script  var code = (0, _utils.getInlineCode)(match); // remove script blocks when all of these lines are comments.  var isPureCommentBlock = code.split(/[\r\n]+/).every(function (line) {  return !line.trim() || line.trim().startsWith('//');        });  if (!isPureCommentBlock) {          scripts.push(match);        }  return inlineScriptReplaceSymbol;      }    });    scriptsscripts = scripts.filter(function (script) {  // filter empty script  return !!script;    });  return {      template: template,      scripts: scripts,      styles: styles,  // set the last script as entry if have not set      entry: entry || scripts[scripts.length - 1]    };  }

最終返回了一個對象,此時已經(jīng)不是一個純html的字符串了,而是一個對象,而且腳本樣式都分離了

微前端框架導(dǎo)入加載子應(yīng)用的方法是什么

這個是框架幫我們處理的,必須要設(shè)置一個入口js文件

// set the last script as entry if have not set

下面是真正的single-spa源碼,注冊子應(yīng)用,用apps這個數(shù)組去收集所有的子應(yīng)用(數(shù)組每一項已經(jīng)擁有了腳本、html、css樣式的內(nèi)容)

微前端框架導(dǎo)入加載子應(yīng)用的方法是什么

此時我們只要根據(jù)我們之前編寫的activeRule和監(jiān)聽前端路由變化去控制展示子應(yīng)用即可,原理如下:(今天不做過多講解這塊)

window.addEventListener('hashchange', reroute);  window.addEventListener('popstate', reroute);  // 攔截所有注冊的事件,以便確保這里的事件總是第一個執(zhí)行  const originalAddEventListener = window.addEventListener;  const originalRemoveEventListener = window.removeEventListener;  window.addEventListener = function (eventName, handler, args) {      if (eventName && HIJACK_EVENTS_NAME.test(eventName) && typeof handler === 'function') {          EVENTS_POOL[eventName].indexOf(handler) === -1 && EVENTS_POOL[eventName].push(handler);     }      return originalAddEventListener.apply(this, arguments);  };  window.removeEventListener = function (eventName, handler) {      if (eventName && HIJACK_EVENTS_NAME.test(eventName) && typeof handler === 'function') {          let eventList = EVENTS_POOL[eventName];          eventList.indexOf(handler) > -1 && (EVENTS_POOL[eventName] = eventList.filter(fn => fn !== handler));      }      return originalRemoveEventListener.apply(this, arguments);  };

也是redux的中間件思想,劫持了事件,然后進(jìn)行派發(fā),優(yōu)先調(diào)用微前端框架的路由事件,然后進(jìn)行過濾展示子應(yīng)用:

export function getAppsToLoad() {      return APPS.filter(notSkipped).filter(withoutLoadError).filter(isntLoaded).filter(shouldBeActive);  }

整個微前端的觸發(fā)流程

微前端框架導(dǎo)入加載子應(yīng)用的方法是什么

到此,相信大家對“微前端框架導(dǎo)入加載子應(yīng)用的方法是什么”有了更深的了解,不妨來實際操作一番吧!這里是創(chuàng)新互聯(lián)網(wǎng)站,更多相關(guān)內(nèi)容可以進(jìn)入相關(guān)頻道進(jìn)行查詢,關(guān)注我們,繼續(xù)學(xué)習(xí)!


文章題目:微前端框架導(dǎo)入加載子應(yīng)用的方法是什么
網(wǎng)頁鏈接:http://www.weahome.cn/article/jiiipo.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部