随着互联网技术的飞速发展,前端领域也在不断地进行着变革。从最初的页面制作,到后来的SPA(单页应用),再到现在的微前端,每一次变革都为我们带来了更多的可能性和挑战。今天,我将带领大家深入探索一个颇具影响力的微前端解决方案——Qiankun。
微前端,顾名思义,就是将一个庞大的前端应用拆分成多个小型、独立的前端应用,每个应用都可以独立开发、测试、部署,最终通过某种方式集成到一起,形成一个完整的应用。这种方式可以有效地解决大型前端项目中的一些问题,如代码耦合度高、开发效率低下等。
Qiankun是一个基于single-spa的微前端实现库。它提供了一种简单、高效的方式来集成多个独立的前端应用。Qiankun的核心思想是通过劫持前端路由,来实现不同应用之间的隔离和通信。
Qiankun通过注册子应用的方式,在主应用中预留出子应用的挂载点。当路由匹配到子应用时,Qiankun会加载子应用的资源,并将子应用挂载到预留的位置。这个过程是动态的,也就是说,子应用可以在任何时候被加载和卸载。
为了保证子应用的独立性,Qiankun为每个子应用创建了一个JS沙箱。这个沙箱可以隔离子应用的全局变量、样式等,防止不同子应用之间的污染。
除了JS沙箱外,Qiankun还提供了样式隔离的功能。通过为每个子应用添加唯一的样式前缀,可以确保子应用的样式不会影响到其他应用。
Qiankun提供了一套完整的应用通信机制。主应用可以通过props向子应用传递数据,子应用也可以通过特定的方式向主应用发送消息。
下面,我们将通过一个简单的例子来演示如何使用Qiankun构建一个微前端应用。
首先,我们创建一个基于Vue的主应用。在主应用中,我们需要安装qiankun
:
npm install qiankun
然后,在Vue项目中设置主应用的路由和子应用的挂载点。
main.js (主应用入口)
import Vue from 'vue';
import App from './App.vue';
import router from './router';
import { registerMicroApps, start } from 'qiankun';
Vue.config.productionTip = false;
new Vue({
router,
render: h => h(App),
}).$mount('#app');
// 注册子应用
registerMicroApps([
{
name: 'micro-app', // 子应用名称
entry: '//localhost:8081', // 子应用入口,可以是相对路径或绝对URL
container: '#micro-container', // 子应用挂载点
activeRule: '/micro-app', // 激活子应用的路由规则
},
]);
// 启动Qiankun
start();
App.vue (主应用组件)
router/index.js (主应用路由配置)
import Vue from 'vue';
import VueRouter from 'vue-router';
Vue.use(VueRouter);
const routes = [
{
path: '/',
name: 'Home',
component: () => import('../views/Home.vue'),
},
// ... 其他主应用路由
];
const router = new VueRouter({
mode: 'history',
base: process.env.BASE_URL,
routes,
});
export default router;
在主应用中,我们已经通过registerMicroApps
方法注册了子应用。现在,让我们看看子应用如何配置。
子应用可以是一个独立的Vue项目,它可以有自己的路由、状态管理和组件等。
子应用的public/index.html
确保子应用的index.html
中没有使用绝对路径引用资源,因为子应用会被加载到主应用的容器中,并且URL将会是基于主应用的。
子应用的main.js
import Vue from 'vue';
import App from './App.vue';
import router from './router';
import store from './store';
let instance = null;
function render(props) {
instance = new Vue({
router,
store,
render: h => h(App),
}).$mount('#app');
}
// 导出qiankun生命周期函数
export async function bootstrap() {
console.log('micro app bootstraped');
}
export async function mount(props) {
render(props);
}
export async function unmount() {
instance.$destroy();
instance.$el.innerHTML = '';
instance = null;
}
if (!window.__POWERED_BY_QIANKUN__) {
render();
}
在上面的代码中,我们导出了三个生命周期函数bootstrap
、mount
和unmount
,它们是Qiankun在加载、挂载和卸载子应用时会调用的。
在主应用中,我们已经为子应用配置了一个激活规则/micro-app
。当路由匹配到这个规则时,Qiankun会自动加载并挂载子应用。
子应用内部的路由应该使用history
模式,并且基础路径应该设置为相对路径,以避免与主应用的路由冲突。
子应用可以像任何常规的SPA应用一样进行开发。它可以有自己的路由配置、组件、状态管理等。
Qiankun提供了几种通信机制,包括props传递、全局状态管理、事件通信等。
通过props传递数据
在主应用中,我们可以在注册子应用时通过props向子应用传递数据:
registerMicroApps([
{
// ... 其他配置
props: { dataFromMain: 'Hello from main app' },
},
]);
在子应用的mount
函数中,我们可以接收这些数据:
export async function mount(props) {
console.log(props.dataFromMain); // 打印 "Hello from main app"
render(props);
}
事件通信
子应用可以通过props
中的onGlobalStateChange
和setGlobalState
函数来与主应用进行全局状态通信。
此外,子应用可以使用window
对象或自定义事件来发送和接收消息,但这种方法不是Qiankun特有的,而是Web开发中常用的一种通信方式。
请注意,以上代码示例仅用于演示目的,并且可能需要根据你的项目结构和需求进行调整。确保你已经正确设置了主应用和子应用的开发环境,并且它们可以独立运行。在整合时,还需要处理跨域、样式隔离、路由冲突等潜在问题。
在使用Qiankun的过程中,我们可能会遇到一些问题,如加载性能、错误处理等。针对这些问题,Qiankun提供了一些优化和扩展的方式。
为了提高应用的加载性能,我们可以使用Qiankun提供的预加载功能。通过预加载,我们可以在用户访问子应用之前,提前加载子应用的资源。
Qiankun提供了一套完整的错误处理机制。当子应用加载失败或运行时出错时,我们可以捕获这些错误,并进行相应的处理。
除了核心功能外,Qiankun还提供了一些扩展功能,如应用状态管理、应用间跳转等。这些功能可以帮助我们更好地管理和控制微前端应用。
特性 | Qiankun | EMP |
---|---|---|
基础技术 | 基于single-spa³ | 基于Webpack 5的Module Federation² |
技术无关性 | 支持,可以使用任何前端框架³ | 支持,但对Webpack有强依赖² |
样式隔离 | 使用Shadow DOM实现³ | 无有效的CSS沙箱² |
JS沙箱 | 使用Proxy和快照两种模式¹ | 无有效的JS沙箱² |
应用间通信 | 提供基于props的通信API¹ | 无明确的通信机制² |
适配成本 | 较高,需要对工程化、生命周期、静态资源路径、路由等进行适配¹ | 对Webpack强依赖,对老旧项目不友好² |
多应用激活 | 不支持¹ | 不支持² |
子应用保活 | 不支持¹ | 不支持² |
附录:
(1) 介绍 - qiankun - umijs.org. https://qiankun.umijs.org/zh/guide.
(2) 微前端wujie、qiankun、micro-app、EMP 方案比较 - 简书. https://www.jianshu.com/p/112920162512.
(3) qiankun 和 emp 在国内微前端中为啥这么受欢迎? - 知乎. https://zhuanlan.zhihu.com/p/406574778.
(4) 微前端技术框架qiankun技术分享 - 知乎 - 知乎专栏. https://zhuanlan.zhihu.com/p/135343332.
(5) undefined. http://example.com.
(6) undefined. https://wujie-micro.github.io/demo-main-vue/home.
(7) undefined. https://github.com/Tencent/wujie.