微前端框架qiankun
简介
Qiankun是一款由蚂蚁金服推出的
微前端框架
,它基于single-spa
进行二次开发,旨在将Web应用由单一的单体应用转变为多个小型前端应用聚合为一的应用。以下是对Qiankun的详细介绍:
一、核心思想
Qiankun借鉴了微服务的架构理念,将一个庞大的前端应用拆分为多个独立灵活的小型应用,每个应用都可以独立开发、独立运行、独立部署,再将这些小型应用联合为一个完整的应用。这种方式既可以将多个项目融合为一,又可以减少项目之间的耦合,提升项目扩展性。
二、主要特性
- 模块化:将大型前端应用拆分为多个小型模块,每个模块都是一个独立的微应用。
- 独立开发:每个微应用可以由不同的团队独立开发,使用不同的技术栈。
- 独立运行:微应用可以独立运行,通过前端路由和页面嵌入等技术实现模块之间的相互调用和通信。
- 独立部署:微应用可以独立部署,无需整个应用重启即可更新单个微应用。
- 技术栈无关性:允许使用不同的编程语言和框架进行开发,提高开发团队的灵活性。
三、关键技术
- 基于路由的拆分:主应用根据路由的变化来加载和卸载不同的微应用。
- Web Components:利用Web Components技术封装微应用,实现组件级别的隔离和复用。但需要注意的是,Web Components的兼容性可能因浏览器而异。
- iframe:通过iframe嵌入微应用,实现简单的隔离和加载。但iframe的隔离性较强,可能导致样式和脚本的冲突。
- 沙箱运行环境:Qiankun提供了沙箱机制,确保微应用之间的全局变量和事件不冲突。沙箱技术通过拦截和修改微应用对全局作用域(如window对象)的访问,实现微应用之间的隔离。
四、使用场景
Qiankun适用于以下场景:
- 大型前端应用需要拆分为多个小型应用,以提高开发效率和可维护性。
- 不同技术栈、不同团队需要独立开发、独立部署的应用。
- 需要实现应用间的增量升级和局部更新。
五、使用示例
以下是一个使用Qiankun搭建Vue微前端应用的简单示例:
- 创建主应用:使用Vue或其他框架创建一个主应用,作为基座项目。在主应用中配置路由、权限等。
- 注册微应用:在主应用中注册需要加载的微应用信息,包括微应用名称、入口地址、挂载节点、激活规则等。
- 启动Qiankun:在主应用的入口文件中引入Qiankun,并调用其提供的API来启动微前端框架。
- 配置微应用:在每个微应用中配置公共路径(public-path),以确保微应用能够正确加载资源。
- 启动应用:分别启动主应用和各个微应用。
六、优势与劣势
优势:
- 技术兼容性好:各个子应用可以基于不同的技术架构。
- 接入方式简单:像使用iframe一样接入微应用。
- 耦合性低:各个团队可以独立开发,互不干扰。
- 可维护性和扩展性好:便于局部升级和增量升级。
劣势:
- 无法支持多实例场景。
- 对Vite等现代前端构建工具的支持不够友好,需要改动较多的代码。
- 子应用间的资源共享能力较差,可能导致项目总体积变大。
- 开发人员需要处理分布式系统的复杂性。
七、总结
Qiankun是一款功能强大的微前端框架,它通过将大型前端应用拆分为多个小型应用,提高了开发效率和可维护性。同时,Qiankun提供了沙箱机制,确保了微应用之间的隔离性。然而,Qiankun也存在一些局限性,如不支持多实例场景、对Vite等构建工具的支持不够友好等。因此,在选择是否使用Qiankun时,需要根据具体项目的需求和团队的技术栈进行综合考虑。
使用
以下是一个完整的例子,用于说明qiankun微前端框架的使用。在这个例子中,我们将创建一个主应用(Angular CLI项目)和一个子应用(Vue CLI项目),并将它们集成在一起。
一、创建主应用(Angular CLI项目)
- 安装Angular CLI并创建项目:
bash
npm install -g @angular/cli
ng new angular-app
cd angular-app
- 安装qiankun:
bash
npm i qiankun --save
-
创建挂载子应用的页面并配置路由:
在Angular项目中创建一个新的组件用于挂载子应用,并配置路由以指向该组件。
bash
ng g component views/vue-page
配置路由(app-routing.module.ts
):
typescript
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { VuePageComponent } from './views/vue-page/vue-page.component';
const routes: Routes = [
{ path: 'home', component: VuePageComponent }
];
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule { }
在VuePageComponent
的HTML模板中添加一个容器元素用于挂载子应用:
html
<div id="container"></div>
-
在主应用中注册子应用:
在
main.ts
中导入qiankun并注册子应用:
typescript
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule } from './app/app.module';
import { registerMicroApps, start } from 'qiankun';
platformBrowserDynamic().bootstrapModule(AppModule)
.catch(err => console.error(err));
registerMicroApps([
{
name: 'vueChildOne',
entry: '//localhost:8080', // 子应用的请求地址
container: '#container', // 挂载到主应用的哪个元素下
activeRule: '/vue-app', // 路由地址为/vue-app时,加载该子应用
}
]);
start();
二、创建子应用(Vue CLI项目)
- 安装Vue CLI并创建项目:
bash
npm install -g @vue/cli
vue create vue-app
cd vue-app
- 安装qiankun:
bash
npm i qiankun --save
-
在子项目中添加public-path.js:
在
src
目录下创建一个public-path.js
文件,并添加以下代码:
javascript
if (window.__POWERED_BY_QIANKUN__) {
__webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__;
}
-
修改Vue项目的入口文件:
在
main.js
中导出生命周期钩子,并处理路由和渲染逻辑:
javascript
import './public-path';
import Vue from 'vue';
import VueRouter from 'vue-router';
import App from './App.vue';
import routes from './router';
Vue.config.productionTip = false;
let router = null;
let instance = null;
function render(props = {}) {
const { container } = props;
router = new VueRouter({
base: window.__POWERED_BY_QIANKUN__ ? '/vue-app' : '/',
mode: 'history',
routes,
});
instance = new Vue({
router,
render: h => h(App),
}).$mount(container ? container.querySelector('#app') : '#app');
}
// 独立运行时
if (!window.__POWERED_BY_QIANKUN__) {
render();
}
export async function bootstrap() {
console.log('[vue] vue app bootstraped');
}
export async function mount(props) {
console.log('[vue] props from main framework', props);
render(props);
}
export async function unmount() {
instance.$destroy();
instance.$el.innerHTML = '';
instance = null;
router = null;
}
-
配置路由:
在
src/router/index.js
中配置路由:
javascript
import Vue from 'vue';
import Router from 'vue-router';
import Home from '@/views/Home.vue';
Vue.use(Router);
const routes = [
{
path: '/',
name: 'Home',
component: Home
},
// 其他路由配置...
];
const router = new Router({
base: process.env.BASE_URL,
mode: 'history',
routes
});
export default router;
-
配置微应用的打包工具:
在
vue.config.js
中添加以下配置,以便主应用能够正确加载子应用的资源:
javascript
module.exports = {
configureWebpack: {
output: {
library: `${name}-[name]`,
libraryTarget: 'umd',
jsonpFunction: `webpackJsonp_${name}`,
},
},
};
三、启动并测试
- 启动子应用:
bash
npm run serve
确保子应用在localhost:8080
上运行(或根据你的配置调整端口)。
- 启动主应用:
bash
ng serve
- 访问主应用:
在浏览器中访问http://localhost:4200/home
(或根据你的Angular项目配置调整端口和路径)。你应该会看到主应用的页面,并且当路由匹配到/vue-app
时,会加载并展示Vue子应用。
通过以上步骤,你就成功地使用qiankun将一个Angular主应用和一个Vue子应用集成在了一起。这只是一个简单的例子,qiankun还支持更多高级功能,如应用间通信、样式隔离等,你可以根据需要进行进一步的配置和开发。
使用场景
微前端框架qiankun的使用场景主要包括以下几个方面:
一、大型前端应用的拆分与整合
-
巨石应用的拆分:
- 在大型前端应用中,随着业务的发展和功能的增加,应用可能会变得非常庞大和复杂,难以维护和扩展。
- 使用qiankun可以将这些大型应用拆分为多个小型、独立的微应用,每个微应用都可以独立开发、部署和迭代,从而提高开发效率和应用的可维护性。
-
多技术栈的整合:
- 在大型项目中,可能会使用多种不同的前端技术栈,如React、Vue、Angular等。
- qiankun支持任意技术栈的应用接入,使得不同技术栈的微应用可以在同一个主应用中协同工作,实现技术的多样性和灵活性。
二、独立开发与部署
- 独立开发 :
- 不同的微应用可以由不同的团队独立开发,每个团队都可以使用自己熟悉的技术栈和工具链。
- 这种独立开发的方式可以提高开发效率,减少团队之间的依赖和冲突。
- 独立部署 :
- 每个微应用都可以独立部署和更新,无需整个应用重启即可更新单个微应用。
- 这种独立部署的方式可以减少更新对整个应用的影响,提高系统的稳定性和可靠性。
三、增量升级与局部更新
- 增量升级 :
- 在面对各种复杂场景时,我们通常很难对一个已经存在的系统做全量的技术栈升级或重构。
- 使用qiankun可以实现微应用的增量升级,即只更新需要升级的微应用部分,而不需要对整个系统进行重构或升级。
- 局部更新 :
- 当某个微应用需要更新时,只需要更新该微应用的代码和资源,而不需要更新整个应用。
- 这种局部更新的方式可以减少更新带来的风险和成本,提高系统的可维护性和可扩展性。
四、应用间的通信与共享
-
应用间通信:
- qiankun提供了多种应用间通信的方式,如全局状态管理、事件总线等。
- 这些通信方式可以使得不同的微应用之间能够方便地传递数据和事件,实现应用间的协同工作。
-
资源共享:
- 在微前端架构中,不同的微应用可能需要共享一些公共的资源或组件。
- qiankun支持在主应用中定义和共享这些公共资源和组件,使得不同的微应用能够方便地复用这些资源和组件。
五、跨域与安全性
-
跨域问题:
- 在微前端架构中,不同的微应用可能部署在不同的域名下,这可能会导致跨域问题。
- qiankun提供了一些解决方案来处理跨域问题,如使用CORS(跨来源资源共享)策略、JSONP等。
-
安全性:
- 微前端架构可能会增加一些安全性问题,如跨站脚本攻击(XSS)、点击劫持等。
- qiankun提供了一些安全措施来防范这些攻击,如使用沙箱机制、内容安全策略(CSP)等。
综上所述,qiankun微前端框架的使用场景非常广泛,适用于大型前端应用的拆分与整合、独立开发与部署、增量升级与局部更新以及应用间的通信与共享等场景。同时,qiankun也提供了一些解决方案来处理跨域问题和安全性问题。
Web Components简介
Web Components是一套技术规范,由一系列不同的Web平台特性组成,允许开发者创建可复用的自定义元素(custom elements)和组件。以下是对Web Components的详细介绍:
一、概念与特点
-
概念:
- Web Components是浏览器环境提供的一套API和模板,支持原生实现组件化。
- 开发者可以方便地创建可重用的定制元素,这些元素具有封装好的结构、样式和脚本。
-
特点:
- 组件化:可以将复杂的UI组件封装成一个可重用的单元,有助于提高开发效率和代码复用性。
- 跨平台:Web Components可以跨浏览器、跨框架使用,不受特定技术栈的限制。
- 隔离性:通过Shadow DOM可以避免组件的样式和行为受到外部影响,提供了良好的隔离性。
- 封装性:提供了一种封装和保护组件内部结构和样式的机制,使得组件的样式和行为不会受到外部的影响。
二、核心组成部分
Web Components实际上是一系列技术的组合,主要包含以下三部分:
-
自定义元素(Custom Elements):
- 在HTML基础标签外扩展自定义标签元素,即平时使用的框架组件。
- 通过
customElements.define()
方法注册自定义元素。
-
Shadow DOM:
- 主要用于将Shadow DOM的内容与外层document DOM隔离。
- 可以理解为在document中的一个子容器,放置各种组件。
- 使用
Element.attachShadow()
方法将一个Shadow DOM附加到自定义元素上。
-
HTML模板(HTML Templates):
- 使用
<template>
来定义组件模板。 <template>
标签内部的内容在初始时不会渲染到页面上,但可以通过JavaScript动态地插入到DOM中。- 使用
<slot>
作为插槽,允许外部内容插入到模板中的指定位置。
- 使用
三、使用场景
-
创建自定义UI元素:
- Web Components允许开发者定义自己的HTML元素,这些元素具有封装好的结构、样式和脚本。
- 可以像标准HTML元素一样在DOM中使用。
-
构建组件化应用:
- 通过Web Components,开发者可以构建组件化的应用,提高代码的复用性和可维护性。
- 每个组件都是独立的,可以单独开发、测试和部署。
-
跨框架开发:
- Web Components是浏览器原生支持的API,因此它们可以在不同的前端框架(如React、Vue)中被无缝集成和使用。
- 这有助于解决不同框架之间的兼容性问题,实现跨框架的组件复用。
四、优势与挑战
-
优势:
- 技术栈无关性:允许使用不同的编程语言和框架进行开发。
- 样式隔离:通过Shadow DOM实现组件样式的隔离,避免样式冲突。
- 性能优化:由于组件的独立性,可以实现对特定组件的缓存和懒加载,提高页面性能。
-
挑战:
- 浏览器兼容性:虽然Web Components已经在现代浏览器中得到了较好的支持,但在一些老旧浏览器中可能仍然存在问题。
- 学习成本:Web Components涉及到多个技术点,需要较高的技术水平和学习成本。
- 性能问题:在某些情况下,Web Components可能会增加网页的加载时间和渲染时间,需要进行优化和测试。
五、未来发展
随着Web Components的不断发展,W3C正在推进Web Components的标准化工作。未来,它将成为Web开发的一个标准特性,得到更广泛的支持和应用。同时,越来越多的组件库和工具链会涌现出来,为Web Components的开发和使用提供更多的支持和便利。
综上所述,Web Components是一种强大的技术,它允许开发者以统一的方式封装自定义的UI组件,并在任何网页上使用。通过充分利用其组件化、跨平台、隔离性和封装性等特性,开发者可以构建出高效、可维护和可扩展的Web应用。