微前端彷佛是最近一個很火的話題,咱們也即將使用在生產環境中,接下來會更新一系列微前端源碼分析、手寫微前端文章javascript
那麼registerMicroApps
,到底作了什麼呢?css
lifeCycles是咱們本身傳入的生命週期函數(這裏先不解釋),跟react這種框架同樣,微前端針對每一個子應用,也封裝了一些生命週期,若是你是小白,那我就用最簡單的話告訴你,生命週期鉤子,其實在框架源碼就是一個函數編寫調用順序而已(有的分異步和同步)html
case 0: entry = app.entry, appName = 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
(子應用地址)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$match = match.match(LINK_HREF_REGEX), _match$match2 = (0, _slicedToArray2["default"])(_match$match, 3), linkHref = _match$match2[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 matchedScriptEntry = match.match(SCRIPT_ENTRY_REGEX); var matchedScriptSrcMatch = 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); } entry = 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; } }); scripts = 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] }; }
// set the last script as entry if have not set
window.addEventListener('hashchange', reroute); window.addEventListener('popstate', reroute); // 攔截全部註冊的事件,以便確保這裏的事件老是第一個執行 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); };
export function getAppsToLoad() { return APPS.filter(notSkipped).filter(withoutLoadError).filter(isntLoaded).filter(shouldBeActive); }
相信經過此文,你能真正瞭解微前端的使用原理,後期我會出一個手寫微前端框架的文章
前端
歡迎加我微信(CALASFxiaotan
),拉你進技術羣,長期交流學習...java
歡迎關注公衆號「前端巔峯」
,認真學前端,作個有專業的技術人...react
點個贊支持我吧,轉發就更好了webpack