微前端
详细描述一下 qiankun 微前端框架的工作原理
qiankun微前端框架可以将多个独立的前端应用组合成一个完整的网站,这些前端应用被称为微前端。下面是其工作原理:
- 父应用加载子应用:父应用通过加载子应用的JavaScript入口文件,实现子应用的动态加载和启动。
- 沙箱机制:qiankun使用沙箱机制来隔离不同的微前端之间的代码和状态,以确保它们之间不会发生冲突。沙箱机制采用了Browser API提供的Iframe标签进行隔离。
- 路由映射:当用户访问一个子应用的路由时,qiankun会将这个路由映射到相应的子应用中去。这样,用户就可以在父应用的菜单栏中快速切换不同的子应用。
- 共享状态:qiankun提供了两种方式来处理不同微前端之间的共享状态:自定义hook函数和props传递。
- 生命周期管理:由于每个微前端都有自己的生命周期,qiankun需要对所有的微前端生命周期进行管理,以便在微前端切换、挂载和卸载时能够正确地执行相应的生命周期函数。
- 更优化的性能:qiankun通过预加载、缓存、静态资源优化等方式实现更加优化的性能。
qiankun微前端框架通过动态加载、沙箱机制、路由映射、共享状态、生命周期管理和性能优化等多种手段实现了微前端的组合和管理。
在使用 qiankun 时,如果子应用为基于 jQuery 的多页应用,应该处理静态资源的加载问题?
如果子应用是基于jQuery的多页应用,我们可以通过qiankun提供的prefetch预加载静态资源来优化性能,具体方法如下:
在子应用中设置webpack的output.publicPath属性为相对路径,以确保子应用可以正确地加载其它静态资源,比如图片、CSS文件等。
// webpack.config.js
module.exports = {
output: {
publicPath: './',
}
};
在父应用种使用registerMicroApps函数注册子应用时,设置微应用的prefetch属性:
// main.js
import { registerMicroApps, start } from 'qiankun';
registerMicroApps([
{
name: 'sub-app',
entry: '//localhost:7100',
container: '#app-container',
activeRule: '/sub-app',
prefetch: true, // 预加载
},
]);
start();
当在父应用中匹配到/sub-app路由时,qiankun会自动预加载子应用入口文件和所有可能需要加载的静态资源。例如,在子应用中访问了一个HTML文件,那么这个HTML文件将会被预加载。
在子应用中手动删除不需要的预加载资源。由于子应用是基于jQuery的多页应用,因此需要手动删除不需要预加载的资源,否则会造成不必要的网络请求浪费。例如,以下代码演示了如何手动删除不需要的预加载资源:
$(function () {
const links = $('link[rel=stylesheet][href]');
const scripts = $('script[src]');
const prefetchedLinks = links.filter('[data-qiankun-prefetch]');
const prefetchedScripts = scripts
.filter('[data-qiankun-prefetch]')
.add($('script[data-qiankun-prefetch]'));
// 删除不需要的预加载资源
links
.not(prefetchedLinks)
.remove();
scripts
.not(prefetchedScripts)
.remove();
});
在DOM渲染完成后,查找所有需要删除的资源,并将其从页面中删除。
在使用 qiankun 时,如果子应用动态插入了一些标签,你会如何处理?
在使用qiankun时,如果子应用动态插入了一些标签,需要做以下处理:
- 使用setExternalScripts和setExternalStyles方法 可以通过setExternalScripts和setExternalStyles方法手动将子应用中动态插入的script和link标签设置为外部资源。这样,qiankun就能正确地处理这些标签,并确保它们不会互相干扰。
具体实现方法如下:
// 在子应用动态插入script标签
const script = document.createElement('script');
script.src = 'https://cdn.example.com/some-script.js';
document.body.appendChild(script);
// 手动设置script标签为外部资源
import { setExternalScripts, setExternalStyles } from 'qiankun';
setExternalScripts([
'https://cdn.example.com/some-script.js',
]);
- 设置自定义导出方法 如果子应用必须动态创建script或link标签,并且这些标签必须动态加载并执行某些代码,可以通过设置自定义导出方法来解决这个问题。
首先,在子应用中定义一个自定义导出方法,例如:
// 子应用中定义自定义导出方法
window.exportMicroAppScript = function (url) {
const script = document.createElement('script');
script.src = url;
document.body.appendChild(script);
};
接着,在父应用注册子应用时,添加getExternalScripts选项,并返回一个对象,该对象包含所有需要在子应用中动态插入的script标签:
// 父应用注册子应用
registerMicroApps([
{
name: 'sub-app',
entry: '//localhost:7100',
container: '#app-container',
activeRule: '/sub-app',
getExternalScripts: [
'https://cdn.example.com/some-script.js',
'https://cdn.example.com/another-script.js',
].map((url) => ({
name: url,
getScript: () => Promise.resolve({ content: window.exportMicroAppScript(url) }),
})),
},
]);
这样,在父应用加载子应用时,qiankun会从getExternalScripts选项中获取所有需要动态插入的script标签,并在合适的时候动态插入到子应用中。
简单来讲: 可以通过手动设置外部资源、自定义导出方法等方式来处理在使用qiankun时子应用中动态插入标签的问题。
在使用 qiankun 时,如何处理老项目的资源加载问题?
在使用qiankun时,如果需要将老项目作为子应用嵌入到父应用中,可能会出现一些资源加载问题,如样式覆盖、命名冲突等。以下是一些具体的解决方案:
- 使用shadow DOM使用shadow DOM可以将子应用的HTML和CSS代码隔离开来,并确保它们不会与父应用的代码冲突。这种方法需要子应用的代码支持shadow DOM,并且需要手动配置。
- 前缀命名 在子应用的HTML和CSS中添加前缀,以避免与父应用的代码冲突。例如,可以在子应用的CSS中添加一个类似于.sub-app-的前缀,以确保所有的选择器都只针对子应用的DOM元素生效。同样地,也可以在子应用中为所有的ID和JavaScript变量添加前缀。
- 自定义主题/样式库 如果子应用中存在大量的公共组件或样式,可以将它们提取到单独的主题/样式库中,以便在多个子应用中共享使用。
- 懒加载 对于不同子应用之间可能出现的重复模块,可以利用webpack的代码分割功能进行懒加载,在父应用中只加载一次,然后在不同的子应用中共享使用。这种方式需要对老项目进行适当的重构,以确保该方案能够正常使用。
- 全局变量定义 可以在父应用中全局定义一些与子应用相关的变量,例如window.subAppPrefix = 'sub-app-';,然后在子应用中使用该前缀来避免与父应用的代码冲突。
假设我们有一个老项目,它是一个单页应用,使用了Bootstrap作为样式库。现在,我们需要将该应用作为子应用嵌入到qiankun的父应用中。
首先,我们可以考虑使用前缀命名的方式来避免与父应用的代码冲突。例如,我们可以在老项目中添加一个类似于.old-app-的前缀,以确保所有的选择器都只针对老项目的DOM元素生效。同时,在父应用中也需要为所有的相应元素添加前缀,例如.sub-app .old-app-。
/* 子应用CSS */
.old-app-button {
background-color: red;
color: white;
}
/* 父应用CSS */
.sub-app .old-app-button {
background-color: blue;
}
其次,我们可以考虑使用自定义主题/样式库的方式来优化样式。我们可以将老项目中使用的Bootstrap样式提取到独立的文件中,并在父应用和子应用中共享使用。
<!-- 子应用HTML -->
<link rel="stylesheet" href="//cdn.example.com/bootstrap.min.css">
<!-- 父应用HTML -->
<link rel="stylesheet" href="//cdn.example.com/bootstrap.min.css">
最后,我们可以考虑使用懒加载的方式来优化性能。我们可以将老项目中重复的模块提取出来,然后在父应用中进行懒加载,并在不同的子应用中共享使用。
// 父应用JavaScript
import('old-app/moduleA').then((module) => {
window.oldAppModuleA = module;
});
// 子应用JavaScript
import('old-app/moduleA').then((module) => {
const result = window.oldAppModuleA.doSomething();
});
解释一下 qiankun 的 start 函数的作用和参数?如果只有一个子项目,你会如何启用预加载?
qiankun的start函数是启动整个微前端应用的函数,用于启动父应用和所有子应用。该函数接受一个可选参数options,其中包含一些配置项,用于控制微前端应用的行为。
start函数主要的作用是:
- 加载并注册所有微应用。
- 根据当前URL匹配合适的微应用,并激活它。
- 监听路由变化,根据新的URL切换微应用。
以下是start函数的常用配置项:
- prefetch:是否开启微应用的预加载,默认值为false。
- sandbox:微应用沙箱的配置,用于隔离微应用中的JavaScript代码和DOM元素。
- singular:是否只允许同时激活一个微应用。
- fetch:自定义的fetch函数,用于加载微应用的HTML内容和JavaScript代码。
如果只有一个子项目时,我们可以通过设置prefetch选项来启用预加载。具体实现方法如下:
registerMicroApps([
{
name: 'sub-app',
entry: '//localhost:7100',
container: '#app-container',
activeRule: '/sub-app',
prefetch: 'all', // 预加载全部静态资源
},
]);
start();
在上述代码中,我们向registerMicroApps函数中传入一个子应用对象,并在其中设置prefetch属性为'all',表示预加载所有静态资源。这样,在父应用启动时,qiankun就会自动预加载子应用的静态资源。
需要注意的是,启用预加载可能会影响微应用的性能和用户体验,因此需要根据实际需求来决定是否启用。
在使用 qiankun 时,如何处理 js 沙箱不能解决的 js 污染问题?
在使用qiankun时,如果出现js沙箱无法解决的js污染问题,可以通过以下方式进行处理:
提高应用安全级别 js沙箱是保护微前端应用免受外部恶意攻击的重要手段之一。因此,我们可以提高应用的安全级别,以减少可能存在的漏洞和被攻击的风险。
使用CDN等资源加速服务 在使用第三方库时,我们可以考虑使用CDN等资源加速服务来加载这些库,并优先选择官方或可信赖的CDN。这样可以减少非法脚本注入的可能性。
对于自己编写的代码,需要注意以下几点:
- 避免使用eval()函数。
- 避免使用Function构造函数。
- 避免使用with语句。
- 避免在全局作用域中定义不必要的变量和函数。
使用CSP(Content Security Policy) CSP是一个HTTP头,它可以让开发者指定网页中可以执行哪些类型的代码。CSP可以限制页面上的JavaScript代码只能够从特定的源加载,并且可以防止页面中注入恶意脚本。因此,我们可以使用CSP来增强应用的安全性。
可以使用js-xss等XSS过滤器来过滤用户输入的HTML和JavaScript代码,以避免XSS攻击。
以上几种方式可以帮助我们处理在使用qiankun时js沙箱无法解决的js污染问题。需要注意的是,在提高应用安全级别和使用CSP等措施时,需要根据实际需求和场景来进行评估和决策。
解释一下 qiankun 如何实现 keep-alive 的需求
qiankun并没有内置keep-alive功能,但我们可以通过一些方法来实现它。
首先,我们可以在父应用中维护一个子应用的缓存列表,例如:
const cachedApps = ['sub-app1'];
然后,在切换微应用时,我们可以判断当前微应用是否需要进行缓存。如果需要,则将其标记为已缓存,并将其DOM元素从页面中移除,以便下次使用时直接显示缓存的结果;否则,直接卸载该微应用。
以下是一个示例代码:
let cacheSubApp = null; // 缓存的子应用
function loadMicroApp(name) {
if (cachedApps.includes(name)) { // 如果需要缓存
if (cacheSubApp && cacheSubApp.name === name) {
return Promise.resolve(cacheSubApp); // 如果已经缓存过了,直接返回缓存结果
}
return loadApp(name).then((app) => {
app.status = NOT_LOADED;
cachedApps.push(name);
const container = document.createElement('div');
container.style.display = 'none';
container.innerHTML = app.template;
document.body.appendChild(container); // 将子应用的DOM元素添加到页面中,方便下次使用时快速显示
app.container = container;
cacheSubApp = app;
return app;
});
} else { // 如果不需要缓存
return unloadMicroApp().then(() => {
return loadApp(name).then((app) => {
app.status = NOT_LOADED;
app.container = document.querySelector('#app-container');
return app;
});
});
}
}
function unloadMicroApp() {
if (cacheSubApp) { // 如果存在缓存的子应用,需要先将其从页面中移除
document.body.removeChild(cacheSubApp.container);
cacheSubApp = null;
}
return Promise.resolve();
}
以上代码中,我们通过判断微应用是否需要缓存,并在需要缓存时将其DOM元素添加到页面中,以便下次使用时直接显示缓存的结果。对于不需要缓存的微应用,则直接卸载它们。
需要注意的是,这种方法可能会导致内存泄漏,因此需要谨慎使用。另外,如果使用了keep-alive功能,则需要确保所有微应用都具有相同的路由结构和状态管理机制,以避免出现一些意料之外的问题。
实际项目中,如基于qiankun进行微前端开发的CRM系统,我们也通常会使用缓存的方式来提高系统的性能和用户体验。例如,在销售订单模块中,我们可以对之前打开过的订单进行缓存,以便下次进入该模块时可以快速显示订单列表。同时,我们也会根据实际需求和场景来评估和决策是否需要开启keep-alive功能。
解释一下 qiankun 和 iframe 在微前端实现方式上的区别和优劣吗?在什么情况下,你会选择使用 iframe 而不是 qiankun
- 技术方案
- qiankun:基于浏览器端路由的容器化微前端框架。
- iframe:基于浏览器多窗口技术的微前端实现方式。
- 性能
- qiankun:通过使用Webpack和SystemJS等技术,可以做到代码分割、按需加载等优化措施,从而提高了性能。
- iframe:因为每个子应用都是独立的窗口,所以可能会存在传输数据量大、渲染性能差等问题。
- 通信
- qiankun:使用自定义事件和全局状态管理来进行子应用之间的通信。
- iframe:使用postMessage API来进行跨域消息通信。
- 安全
- qiankun:使用JavaScript沙箱隔离子应用中的代码和DOM元素,增强了应用的安全性。
- iframe:在跨域访问时,需要考虑一些安全问题,例如防止XSS攻击、防止iframe嵌套等。
在微前端开发中,我们应根据实际情况选择合适的实现方式。在一些简单的场景中,我们可以使用iframe来进行微前端开发;在一些复杂的场景中,我们可以使用qiankun等容器化框架来进行微前端开发。
当需要实现跨域通信、隔离子应用代码和DOM元素、动态加载等功能时,qiankun是一种更好的选择。如果只需要简单地将多个独立的Web应用程序组合在一起,或者需要实现多窗口操作等功能时,可以尝试使用iframe。
需要注意的是,在使用iframe时,需要考虑其性能、安全和可用性等问题,并做好相关的优化措施。
qiankun是如何实现CSS隔离的,该方案有什么缺点,还有其它方案么?
在qiankun中,CSS隔离是通过为每个子应用创建一个独立的命名空间来实现的。具体地说,当我们把一个子应用注册到qiankun中时,qiankun会根据该应用的名称创建一个唯一的前缀,并将这个前缀添加到该应用中所有CSS选择器的前面。
例如,如果我们有两个子应用A和B,它们都使用了名为.button的CSS类,则qiankun会自动将应用A中的.button转换为.app-A-button,将应用B中的.button转换为.app-B-button。这样,就能够避免不同子应用之间的CSS冲突。
该方案的主要优点是简单易用,不需要对子应用的代码进行修改,也不需要额外的编译过程。另外,在多个子应用中共享组件库或UI库时,这种方案也能够很好地解决样式冲突问题。
然而,该方案也存在一些缺点。首先,这种方法只适用于CSS的隔离,而无法隔离其他资源(如JavaScript、图片等)。其次,由于需要为每个子应用创建一个唯一的前缀,可能会导致CSS文件增大,从而影响加载和渲染性能。此外,对于一些比较复杂的CSS选择器,可能会出现无法正确转换的情况。
除了qiankun之外,还有一些其它方案可以用来实现多个子应用之间的CSS隔离。例如:
- 在子应用中使用CSS Modules
在子应用中使用CSS Modules来实现样式的局部作用域,从而避免样式冲突问题。例如,在React项目中,我们可以使用css-loader和style-loader等工具来启用CSS Modules,并设置localIdentName选项来生成唯一的类名。
// webpack.config.js
module.exports = {
module: {
rules: [
{
test: /\.css$/,
use: [
'style-loader',
{
loader: 'css-loader',
options: {
modules: {
localIdentName: '[name]__[local]___[hash:base64:5]',
},
},
},
],
},
],
},
};
然后,在JSX代码中,我们可以通过import styles from './styles.module.css'来引入样式表,并使用
- 使用Webpack的CSS Scope插件
使用Webpack的CSS Scope插件能够自动为CSS选择器添加前缀,从而实现CSS隔离。例如,在webpack.config.js文件中,我们可以添加css-loader插件,并设置scopeBehaviour选项为global或local,以控制是否需要进行CSS隔离。
// webpack.config.js
module.exports = {
module: {
rules: [
{
test: /\.css$/,
use: [
{
loader: 'css-loader',
options: {
modules: {
scopeBehaviour: 'local', // 控制是否需要进行CSS隔离
},
},
},
],
},
],
},
};
- 使用Shadow DOM
使用Shadow DOM将每个子应用包装在一个独立的Shadow DOM中,从而实现CSS、DOM和JavaScript的完全隔离。例如,在Vue项目中,我们可以在App.vue组件中创建一个Shadow DOM,并将子组件插入到其中。
<!-- App.vue -->
<template>
<div class="container">
<div class="app1">
<slot name="app1"></slot>
</div>
<div class="app2">
<slot name="app2"></slot>
</div>
</div>
</template>
<script>
export default {
mounted() {
const container = this.$el;
const shadowRoot = container.attachShadow({ mode: 'open' });
const app1Slot = document.createElement('slot');
app1Slot.setAttribute('name', 'app1');
shadowRoot.appendChild(app1Slot);
const app2Slot = document.createElement('slot');
app2Slot.setAttribute('name', 'app2');
shadowRoot.appendChild(app2Slot);
},
};
</script>
然后,在父应用中,我们可以使用mount函数来将子应用挂载到相应的位置上。
// main.js
import { registerMicroApps, start } from 'qiankun';
registerMicroApps([
{
name: 'app1',
entry: 'http://localhost:3001',
container: '#app1',
activeRule: '/app1',
},
{
name: 'app2',
entry: 'http://localhost:3002',
container: '#app2',
activeRule: '/app2',
},
]);
start();
需要注意的是,在使用Shadow DOM时,我们还需要考虑一些浏览器兼容性、性能和安全等问题,并做好相关的优化和测试工作。
qiankun中如何实现父子项目间的通信?
在qiankun中,父子项目间的通信可以通过以下几种方式来实现:
- 全局变量:在父应用和子应用之间设置一个全局变量,用于共享数据。例如,我们可以在父应用中定义一个全局对象,并将其暴露给子应用使用。
// 在父应用中定义一个全局对象
window.sharedData = {
userName: '钟翰',
};
// 在子应用中读取全局变量
const userName = window.parent.sharedData.userName;
- CustomEvent:使用浏览器提供的CustomEvent事件,可以在父子应用之间发送消息并接收消息。例如,我们可以在父应用中使用window.dispatchEvent()方法发送一个CustomEvent事件,并在子应用中使用window.addEventListener()方法监听该事件。
// 在父应用中发送一个CustomEvent事件
const event = new CustomEvent('eventName', { detail: { data: 'hello' } });
window.dispatchEvent(event);
// 在子应用中监听CustomEvent事件
window.addEventListener('eventName', (event) => {
console.log(event.detail.data);
});
- postMessage:使用postMessage可以实现跨域窗口之间的通信。在父应用和子应用之间,我们可以使用window.postMessage()方法发送消息,并使用window.addEventListener()方法监听消息。
// 在父应用中发送postMessage消息
const targetWindow = document.getElementById('child-iframe').contentWindow;
targetWindow.postMessage({ type: 'message', data: 'hello' }, '*');
// 在子应用中监听postMessage消息
window.addEventListener('message', (event) => {
if (event.data.type === 'message') {
console.log(event.data.data);
}
});
在主项目中使用qiankun注册子项目时,如何解决子项目路由的hash与history模式之争?
在使用qiankun注册子应用时,路由的hash与history模式的选择是比较重要的问题。下面是一些解决方案供参考:
- 统一使用hash模式
这种方式的好处是简单易用,不需要额外的配置和调整就可以正常工作。同时也避免了多个子应用之间路由冲突的问题。但是,使用hash模式会使URL显得比较丑陋,并且在SEO、链接分享等方面存在一定的局限性。
- 统一使用history模式
这种方式可以使URL更加美观,符合现代化的设计理念,同时也对SEO、链接分享等有一定的优化效果。但是,在使用多个子应用时,需要确保每个子应用的路由名称不会冲突,否则可能会导致路由冲突的问题。
- 自适应模式
这种方式可以根据当前页面的路径来自适应地选择使用hash或者history模式。在qiankun中,可以使用master应用的history对象来获取当前页面的路径信息,然后通过判断路径中是否包含子应用的前缀来决定使用哪种路由模式。
import { registerMicroApps, start } from 'qiankun';
registerMicroApps([
{
name: 'app1',
entry: '//localhost:8081',
activeRule: '/app1',
},
{
name: 'app2',
entry: '//localhost:8082',
activeRule: '/app2',
},
]);
start();
const useHash = window.location.pathname.indexOf('/app1') !== -1;
const routerType = useHash ? 'hash' : 'history';
registerMicroApps(
[
{
name: 'app1',
entry: '//localhost:8081',
activeRule: '/app1',
props: { routerType },
},
{
name: 'app2',
entry: '//localhost:8082',
activeRule: '/app2',
props: { routerType },
},
],
{
// ...
}
);
需要注意的是,在使用自适应模式时,需要确保每个子应用都可以适应两种路由模式,并对其进行相应的调整和优化。同时,在处理URL参数等方面也需要做好兼容性处理,以保证系统的稳定性和可靠性。
说说qiankun的资源加载机制(import-html-entry)
qiankun使用了一种名为import-html-entry的资源加载机制,该机制基于动态导入和HTML解析技术,可以动态地加载子应用所需的资源,并将其注入到DOM中。具体来说,该机制主要包括以下几个步骤:
- 解析HTML
首先,qiankun会从子应用的entry地址中获取HTML内容,并对其进行解析和处理。在解析过程中,qiankun会识别出需要加载的JS、CSS和其他资源,并通过动态创建link、script等标签来动态加载这些资源。
- 加载JS
在加载JS时,qiankun会利用浏览器的动态导入特性来异步加载JS模块。在加载完毕后,qiankun会调用JS的导出函数来获取子应用的组件、路由和其他配置信息,并将其保存到内存中。
- 加载CSS
在加载CSS时,qiankun会通过动态创建link标签来异步加载CSS文件。在加载完毕后,qiankun会将CSS样式表插入到head标签中。
- 创建Sandbox环境
在加载完所有资源后,qiankun会根据已有的配置信息创建一个沙箱环境,用于隔离和保护子应用的运行环境。在沙箱环境中,qiankun会重写全局变量、监听事件等操作,以确保子应用的运行不会影响到父应用和其他子应用。
- 渲染组件
在沙箱环境创建完毕后,qiankun会根据配置信息渲染出子应用的组件,并将其插入到父应用的DOM中。同时,qiankun还会监听子应用的路由变化,并进行相应的跳转和渲染。
需要注意的是,import-html-entry机制并非绝对适用于所有场景,具体使用时需要考虑一些安全性、可扩展性和易用性等问题,并结合其他技术如发布系统、版本控制等工具来提高开发效率和用户体验。
还了解其他微前端框架么,简单讲一下?
- qiankun
优点:
- 完整的生命周期控制:支持子应用的启动、挂载、卸载等操作,可灵活处理不同场景下的生命周期问题。
- 智能化路由管理:支持多种路由模式,可以自适应根据当前页面路径来选择使用history或hash模式。
- 灵活的组件通信方式:支持props传递、全局状态管理、事件订阅等方式进行组件间通信,可以满足不同粒度和复杂度的通信需求。
- 内置的沙箱环境:支持自定义沙箱配置和策略,可以有效地隔离和保护子应用的运行环境。
- 开放的插件机制:支持第三方插件开发和集成,可以扩展和定制不同的功能和特性。
缺点:
- 集成和维护成本较高:需要对多个技术栈和应用进行统一管理和调度,在维护和更新方面需要投入更多的人力和资源。 8 对已有应用的适配需要一定的工作量:需要对现有应用进行改造和调整,以适配qiankun的运行和配置要求。
- single-spa
优点:
- 多框架兼容:支持多种前端框架,如React、Angular、Vue等。
- 完整的生命周期控制:支持子应用的启动、挂载、卸载等操作,可灵活处理不同场景下的生命周期问题。
- 灵活的路由管理:支持自定义路由规则,可以灵活处理各种路由场景和需求。
- 多重通信机制:支持全局状态管理、事件总线、props传递等多种方式进行组件间通信。
缺点:
- 部分功能需要手动实现:single-spa本身只提供了基础的生命周期控制和路由管理功能,一些其他的特性和功能需要手动实现。
- 学习成本较高:single-spa对模块化和异步加载技术有一定要求,在学习和使用时需要投入更多的时间和精力。
- 对已有应用的适配需要一定的工作量:需要对现有应用进行改造和调整,以适配single-spa的运行和配置要求。
- 微前端q-mic
优点:
- 基于vue.js的开发:针对webapp前端单页应用,基于vue.js进行搭建,微前端的应用在处理上相对简便。
- 支持嵌套子应用:q-mic可以嵌套无限层的子应用。
- 采用shadow dom:各子应用之间的样式和DOM元素是相互隔离的,使用shadow dom实现。
缺点:
- 社区较小:q-mic是一个比较新的微前端框架,目前在国内的使用者较少,相对来说其社区支持与生态完善度还不如qiankun等已有的框架。
- 可拓展性不高:由于q-mic是基于Vue.js进行的开发,因此如果想要在非Vue.js项目中使用,就需要自己去做一些改造和适配工作了。