了解微前端
微前端(Micro Frontends)是一种架构风格,其中前端应用被划分为更小、更独立、更容易管理的部分。这些部分通常被称为"微应用",每个微应用都有自己的责任范围,并且能够独立开发、部署和运行。
微前端的核心理念是将大型前端项目分解成多个小的、自主的部分,并将它们组合成一个完整的应用。这种方法有几个关键优点:
- 自治性:团队可以独立地开发和部署自己负责的微应用,这有助于提高开发速度和效率。
- 技术栈无关:不同的微应用可以使用不同的技术栈开发,只要它们能够在主应用中合作运行。
- 简化升级:更新或升级应用的某个部分不需要重写整个应用,只需要更新相关的微应用。
- 更易维护:每个微应用都较小,更容易理解和维护。
微前端架构的实现通常涉及以下几个方面:
- 集成层:负责将不同的微应用组合起来呈现给用户。这可以通过多种方式实现,比如使用Web Components、iframe、JavaScript库(如single-spa)或简单的路由分发。
- 通信机制:微应用之间可能需要通信,这可以通过浏览器事件、全局状态管理库(如Redux)或者专门设计的服务来实现。
- 部署独立性:每个微应用应该能够独立部署,不影响其他微应用或主应用的运行。
- 共享依赖:微应用间可能会有一些共享的库或组件,通过合理管理这些共享依赖可以减少冗余和加载时间。
实现微前端的方法多种多样,但是有一些常见的模式和工具,比如:
- single-spa:一个用于前端微服务的JavaScript库,允许你使用多种前端框架并存。
- Module Federation:Webpack的一个功能,允许一个运行时动态的应用从另一个应用加载代码。
- SystemJS:一个模块加载器,可以在运行时动态加载各种模块格式。
微前端架构适合大型组织和项目,因为它可以帮助分散风险,提高开发效率,并允许不同团队使用他们选择的技术栈工作。然而,它也带来了一些挑战,比如确保设计和用户体验的一致性,管理跨团队的协作,以及处理潜在的运行时冲突和依赖问题。
微前端解决了什么问题
微前端架构解决了在大型、复杂的前端项目中常见的一些问题,特别是在多团队协作的情况下。
- 团队自治:微前端使不同的团队能够在技术栈、开发过程和部署策略上独立工作,而不影响其他团队。
- 技术敏捷性:每个微前端团队都可以独立选择和升级他们的技术栈,这使得采用新技术或升级旧技术变得更加容易和快速。
- 代码维护和可管理性:通过将大型前端应用分解为更小的部分,每个部分都更易于理解、维护和测试。
- 可扩展性:随着应用的增长,新增功能或团队时,微前端架构提供了良好的扩展性。
- 部署独立性:各个微前端可以独立部署,不需要整个前端应用进行重新部署,这减少了部署风险并提高了发布速度。
- 减少代码冲突和依赖问题:由于各个微前端可以独立开发和部署,不同团队之间在代码层面的直接依赖和冲突被大大减少。
- 并行开发:不同的团队可以同时在不同的特性和模块上工作,加快开发进度。
- 灵活的产品迭代:可以针对特定用户或业务需求快速迭代微前端的某个部分,而不必等待整个应用的更新。
- 改善性能:可以根据需要加载特定的微前端,而不必在首次加载时加载整个应用的所有代码,这有助于提高性能。
- 容错性:微前端的一个部分出现故障不会影响到整个应用,从而提高了整体的容错性和稳定性。
在解决这些问题的同时,微前端架构也带来了自己的挑战,例如潜在的复杂性增加、跨微应用的一致性保证、通信和状态管理的复杂性、以及运行时集成可能导致的性能和安全问题。因此,在采用微前端之前,需要仔细考虑这些权衡。
适用场景
主要使用于后台比较分散,体验差别大,单页面应用庞大、多人合作成本高的场景
框架选择
在框架选择中,主要参考了蚂蚁的qiankun 和淘宝的ice/stark,两个框架在使用上差别并不大,考虑到ice/stark将数据管理和shadowdom做了单独的包拆分,可以根据业务需求做取舍,个人最终选择了ice/stark作为核心框架;
qiankun | ice/stark | |
---|---|---|
注册组件 | registerMicroApps | AppRouter/AppRoute |
htmlEntry | ✅ | ✅ |
JsEntry | ✅ | ✅ |
按需加载 | ✅ | ✅ |
js 隔离 | 沙箱 | 沙箱 |
css 隔离 | shadow-dom | cssModule |
子应用单独运行 | ✅ | ✅ |
子应用唤起方式 | 路由/手动 | 路由/手动(2.0) |
轻量 | ❌ | ✅ |
指定的插入dom | ✅ | 2.0 |
ice/stark具体实现
应用注册与加载
js
// 在主应用中注册微应用
import { registerMicroApps } from '@ice/stark';
registerMicroApps([
{
name: 'microApp1',
entry: '//localhost:3001',
path: '/micro-app-1',
title: 'Micro App 1',
// 其他配置...
},
// 可以注册更多的微应用...
]);
应用生命周期管理
ce/stark
提供了一系列的生命周期钩子,允许你定义微应用在不同阶段的行为,如挂载(mount)、卸载(unmount)、更新(update)等。
js
registerMicroApps([
{
name: 'microApp1',
entry: '//localhost:3001',
mount: [appMount],
unmount: [appUnmount],
// ...其他配置
},
]);
// 微应用挂载时的操作
function appMount(appInfo) {
console.log(`${appInfo.name} is mounted`);
}
// 微应用卸载时的操作
function appUnmount(appInfo) {
console.log(`${appInfo.name} is unmounted`);
}
应用间通信
主要通过ice提供的@ice/stark-data模块包实现,它支持状态共享和事件监听响应两种方式
JavaScript 沙箱
为了防止微应用间的全局变量冲突,ice/stark
使用 JavaScript 沙箱来隔离不同微应用的运行环境。这可以通过 Proxy 等现代 JavaScript 特性来实现。
样式隔离
ice/stark
提供了样式隔离的能力,确保各个微应用的样式不会相互影响。这通常是通过命名空间或构建工具中的 CSS Modules 特性来实现的。