实现微前端的十种方式 【第二种】

实现微前端的十种方式 【二】

  • 实现微前端,我想了一想,大概有十种方式
  • 想学习微前端的小伙伴,可以看我之前对微前端源码解析、加载方式、以及我开源的微前端框架chunchao源码
  • 简单的文章,通俗易懂,感觉不错记得点个在看关注

目前主流的微前端实现方式(基座加载式)

  • 以基座为入口,配置不同的子应用入口地址,达到实现微前端的效果
  • 目前微前端开源的框架:chunchaoqiankun,其中chunchao仅仅200行代码就实现了,是一个非常值得定制开发的微前端雏形框架
  • 微前端基座模式配置

  • 加载示意图

如何实现基座模式加载子应用?

  • 劫持前端路由,重写hashchangepopstate事件

const HIJACK_EVENTS_NAME = /^(hashchange|popstate)$/i;

const EVENTS_POOL = {

hashchange: [],

popstate: [],

};

window.addEventListener('hashchange', loadApps);

window.addEventListener('popstate', loadApps);

const originalAddEventListener = window.addEventListener;

const originalRemoveEventListener = window.removeEventListener;

window.addEventListener = function (eventName, handler) {

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);

};

  • 根据不同的入口,去拉取子应用的jscss等资源

  • 注册子应用后存入队列中

/**

*

* @param {string} entry

* @param {string} function

*/

const Apps = [] //子应用队列

function registryApp(entry,activeRule) {

Apps.push({

entry,

activeRule

})

}

  • 注册完了之后,就要找到需要加载的app,并且拉取资源

export async function loadApp() {

const shouldMountApp = Apps.filter(shouldBeActive);

const App = shouldMountApp.pop();

fetch(App.entry)

.then(function (response) {

return response.text();

})

.then(async function (text) {

const dom = document.createElement('div');

dom.innerHTML = text;

const entryPath = App.entry;

const scripts = dom.querySelectorAll('script');

const subapp = document.querySelector('#subApp-content');

const paromiseArr =

scripts &&

Array.from(scripts).map((item) => {

if (item.src) {

const url = window.location.protocol + '//' + window.location.host;

return fetch(`${entryPath}/${item.src}`.replace(url, '')).then(

function (response) {

return response.text();

}

);

} else {

return Promise.resolve(item.textContent);

}

});

subapp.appendChild(dom);

const res = await Promise.all(paromiseArr);

if (res && res.length > 0) {

res.forEach((item) => {

const script = document.createElement('script');

script.innerText = item;

subapp.appendChild(script);

});

}

});

}

  • shouldBeActive根据传入的规则去判断是否需要此时挂载:

export function shouldBeActive(app){

return app.activeRule(window.location)

}

  • 处理脚本文件

export async function handleScripts(entryPath,subapp,dom) {

const scripts = dom.querySelectorAll('script');

const paromiseArr =

scripts &&

Array.from(scripts).map((item) => {

if (item.src) {

const url = window.location.protocol + '//' + window.location.host;

return fetch(`${entryPath}/${item.src}`.replace(url, '')).then(

function (response) {

return response.text();

}

);

} else {

return Promise.resolve(item.textContent);

}

});

const res = await Promise.all(paromiseArr);

if (res && res.length > 0) {

res.forEach((item) => {

const script = document.createElement('script');

script.innerText = item;

subapp.appendChild(script);

});

}

}

  • 处理样式文件

export async function handleStyles(entryPath, subapp, dom) {

const arr = [];

const styles = dom.querySelectorAll('style');

const links = Array.from(dom.querySelectorAll('link')).filter(

(item) => item.rel === 'stylesheet'

);

const realArr = arr.concat(styles,links)

const paromiseArr =

arr &&

Array.from(realArr).map((item) => {

if (item.rel) {

const url = window.location.protocol + '//' + window.location.host;

return fetch(`${entryPath}/${item.href}`.replace(url, '')).then(

function (response) {

return response.text();

}

);

} else {

return Promise.resolve(item.textContent);

}

});

const res = await Promise.all(paromiseArr);

if (res && res.length > 0) {

res.forEach((item) => {

const style = document.createElement('style');

style.innerHTML = item;

subapp.appendChild(style);

});

}

}

  • 此时,我们已经可以加载不同的子应用了。

最后

  • 认真收藏这个系列吧,记得点个关注和在看,相信你能收获很多很多~
  • 我是Peter,架构设计过桌面跨平台IM软件、重型Saas平台以及手机端跨平台APP,我的微信:CALASFxiaotan
  • 另外欢迎收藏我的资料网站:前端生活社区:https://qianduan.life,感觉对你有帮助,可以右下角点个在看关注一波公众号:[前端巅峰]

以上是 实现微前端的十种方式 【第二种】 的全部内容, 来源链接: utcz.com/a/30776.html

回到顶部