wujie 和 qiankun 都是用于构建微前端(Micro Frontend)架构的 JavaScript 框架,它们都致力于实现多个独立前端子应用的整合与协同工作。不过,它们在设计理念、实现方式以及使用体验等方面有较大区别。
以下是两者的对比,包括主要区别、各自优缺点:
一、基本概念对比
| 特性 | wujie | qiankun |
|---|---|---|
| 核心理念 | iframe + sandbox 的轻量组合 | 基于 single-spa,注重生命周期管理 |
| 应用加载方式 | 类似 iframe 的嵌入式(隔离性强) | Script 注入 + 沙箱实现全局变量隔离 |
| 沙箱机制 | 利用 iframe 的天然隔离 + proxy + snapshot | JS 沙箱(proxy + patch) |
| 架构复杂度 | 较低,接入简单 | 架构较重,接入和调试略复杂 |
二、wujie 框架详解
✅ 优点:
- 隔离性强:通过 iframe 实现的隔离,使子应用与主应用之间几乎无污染。
- 支持任意技术栈:不仅限于 Vue/React 等主流框架,几乎任何前端项目都可以作为子应用接入。
- 实现简单:项目接入成本低,无需修改大量子应用逻辑。
- 预加载与懒加载:性能优化较好。
- 内置多种通信机制:支持 postMessage、全局事件总线、props 等多种通信方式。
❌ 缺点:
- 部分功能依赖 iframe,存在 SEO 屏蔽、样式继承困难等问题。
- 由于隔离性太强,某些主子应用间共享资源(如样式变量、状态)比较麻烦。
- 文档生态相对较少(比 qiankun 成熟度略低,但社区在成长)。
三、qiankun 框架详解
✅ 优点:
- 主流微前端方案,社区活跃度高,资料丰富。
- 生命周期完整:可以控制子应用的 mount/unmount/init 等,适合大型项目管理。
- 沙箱机制成熟:通过
proxy实现 JS 隔离,较好地解决了全局变量污染问题。 - 共享依赖管理:可以在主应用与子应用之间共享包依赖,减少重复加载。
❌ 缺点:
- 技术栈耦合偏高:更适用于 Vue/React 子应用,其他技术栈接入可能需要较多改造。
- 接入成本高:需要严格遵守 single-spa 生命周期和配置要求。
- 沙箱隔离不如 iframe 强:可能存在样式、全局变量泄露问题。
- 调试复杂度高:项目一旦大了,调试子应用变得麻烦。
四、适用场景对比
| 使用场景 | 推荐框架 | 理由 |
|---|---|---|
| 快速集成老系统 | wujie | 接入成本低,几乎不需要对子应用大改动 |
| SEO 要求不高、追求隔离性强 | wujie | iframe 提供天然隔离,稳定可靠 |
| 需要精细控制子应用生命周期 | qiankun | 生命周期完整,适合大型项目 |
| Vue/React 项目体系为主 | qiankun | 社区更成熟,框架兼容更好 |
| 多技术栈混合(如 Angular + React) | wujie | iframe 适配各种技术栈,避免冲突 |
五、总结
| 对比维度 | wujie | qiankun |
|---|---|---|
| 性能 | 较好(预加载+懒加载) | 依赖优化处理后表现良好 |
| 安全隔离 | 强(iframe + 沙箱) | 一般(JS 沙箱) |
| 接入复杂度 | 较低 | 较高 |
| 子应用兼容性 | 高(技术栈无关) | 中(偏向 Vue/React) |
| 生命周期管理 | 支持但较简单 | 完善 |
| 社区成熟度 | 一般 | 高 |
除了 qiankun 和 wujie 之外,还有什么其他的微前端框架
1. single-spa
介绍:
- single-spa 是一个流行的微前端框架,支持多个框架(如 React、Vue、Angular)在同一个页面上共存。它的设计核心是让你能够独立加载和卸载前端应用,而不影响其他应用的运行。
特点:
- 支持多种前端框架同时运行,允许子应用使用不同的框架(如 React 和 Vue 同时运行)。
- 通过 生命周期管理 让子应用的加载、卸载、更新都更加灵活。
- 对微前端有良好的控制,适用于复杂场景。
优点:
- 灵活性强,可以在一个页面中同时运行多个框架的子应用。
- 支持子应用生命周期的精细管理。
- 社区活跃,使用广泛,文档资料丰富。
缺点:
- 需要一些前提配置,集成起来相对较复杂。
- 对子应用的开发要求较高,尤其是在框架间的资源共享和通信上。
2. Mosaic
介绍:
- Mosaic 是一个支持多框架微前端架构的框架,目标是让开发者可以在一个单独的应用中使用多个微前端子应用。它的设计原则是组件化,通过基于 Vue 或 React 的组件容器来实现。
特点:
- 支持将多个独立的应用通过组件化的方式挂载到一个页面上。
- 提供了一些方便的工具来管理子应用和主应用之间的通信。
优点:
- 支持组件级的微前端,而不是应用级,适用于场景较轻量的微前端需求。
- 易于集成。
缺点:
- 相比 qiankun 和 single-spa,文档和社区支持较少。
3. Module Federation (Webpack 5)
介绍:
- Module Federation 是 Webpack 5 中新增的功能,旨在让多个 Webpack 构建的模块能够共享和动态加载。
- 通过模块共享,前端应用可以跨应用共享依赖、组件或功能,不需要每个应用都重复打包相同的内容。
特点:
- 通过 Module Federation,可以将各个应用的某些部分(如组件、模块、库)共享给其他应用。
- 支持动态加载和共享应用代码,减少了冗余的依赖。
优点:
- 解决了微前端中的“依赖共享”问题。
- 可以按需加载应用,优化性能。
- 在构建工具层面进行微前端集成,减少了框架间的耦合度。
缺点:
- 需要 Webpack 5 及以上版本。
- 配置和调试相对复杂,尤其是对于初学者来说。
4. Luigi Framework
介绍:
- Luigi 是由 SAP 提供的一个微前端框架,适用于构建企业级的应用。它通过将不同的微前端模块组合到一个单一的用户界面中来创建大规模的应用。
特点:
- 提供了一个基于 URL 的路由系统,用于管理微前端应用的导航。
- 支持前后端分离的微前端架构。
- 提供了一些 UI 组件和功能来帮助开发者实现微前端集成。
优点:
- 适合企业级应用,尤其是需要多个团队开发的系统。
- 提供的路由和导航解决方案非常强大。
缺点:
- 相比于其他框架,社区较小,文档和支持不如其他主流框架。
- 需要较为复杂的配置,适合复杂的应用场景。
5. FrintJS
介绍:
- FrintJS 是一个功能强大的微前端框架,支持多个前端应用并且通过模块化的方式来拆分和管理应用。它专注于大规模的微前端架构,能够实现高度解耦的前端组件。
特点:
- 提供了构建和管理微前端应用的全栈方案,支持应用和模块的动态加载。
- 使用 FrintJS 构建的应用之间通过框架提供的 API 进行通信,保持良好的解耦性。
优点:
- 提供了较强的模块化支持,适合开发复杂的微前端架构。
- 支持多框架、多技术栈共存。
缺点:
- 文档和社区支持相对较少,开发者需要对框架有较深入的了解。
- 对入门门槛较高,可能不适合小型项目。
6. MFE (Micro Frontend) 的自定义实现
介绍:
- 除了现成的框架外,一些团队也选择自行实现微前端架构,通常会基于 iframe、Web Components、Module Federation 等技术,定制符合自己需求的微前端解决方案。
特点:
- 可以根据自己的需求选择最合适的技术栈。
- 灵活性非常高,但需要较强的技术积累。
优点:
- 高度定制化,灵活性强。
- 不受现有框架限制,可以完全按照业务需求实现。
缺点:
- 开发成本高,需要较多的技术积累。
- 缺少统一的标准和解决方案,可能导致后期维护困难。
总结
- qiankun 和 wujie 作为目前较为流行的微前端框架,适用于大多数常见场景。
- single-spa 更加灵活,适用于不同框架的共存,适合复杂的微前端需求。
- Module Federation 是 Webpack 5 中的一个特性,可以用于构建微前端,解决了模块共享的问题。
- 其他框架如 Luigi、FrintJS 适合特定需求,如企业级系统或高度模块化的架构。
补充汇总:
§ 说一下 webpack module 联邦是什么
Webpack Module Federation(模块联邦) 是 Webpack 5 引入的一个新特性,用于支持微前端架构以及跨应用共享模块的功能。它的核心目标是允许不同 Webpack 构建的应用之间共享代码和资源,而不需要每个应用都重复打包相同的模块,从而减少冗余、提升性能并优化开发体验。
基本概念
Module Federation 让你在多个独立的 Webpack 构建中共享模块(如 JavaScript、CSS、React 组件等)。这对于微前端架构尤为重要,因为它可以让不同的应用(无论是子应用还是主应用)之间共享一些公共模块,而不需要在每个应用中单独打包。
模块联邦的关键点
- 共享模块:不同应用可以共享模块(例如 React、Vue、某些第三方库或自定义组件),从而避免重复加载相同的代码。
- 动态加载:可以动态地加载共享模块,而不需要在构建时就确定所有依赖关系。
- 远程加载:一个应用可以远程加载另一个应用的代码,并在运行时直接使用它。
Module Federation 的核心功能
Module Federation 主要通过以下方式工作:
-
共享模块:
- exposes:在一个应用中暴露出某些模块,供其他应用使用。
- remotes:其他应用可以远程加载这些暴露出来的模块。
-
自动依赖管理:
- 不同的应用可以共享相同的依赖库(如 React、Vue 等)。如果这些库已经加载过,Webpack 会自动处理模块的共享和版本控制,避免重复加载。
应用场景
-
微前端架构:
- 在微前端架构中,不同的子应用可以使用 Module Federation 共享一些公共的模块,减少应用间的重复代码和依赖。
-
跨应用共享组件:
- 假设你有多个前端应用(如购物网站、用户管理系统等),你可以通过 Module Federation 在它们之间共享 UI 组件、逻辑模块等,而不需要每个应用独立构建这些组件。
工作原理
1. 主应用暴露模块
在主应用的 Webpack 配置中,你可以使用 exposes 来暴露模块供其他应用使用。
// webpack.config.js for host (主应用)
module.exports = {
// 在 Module Federation 插件中设置 exposes
plugins: [
new webpack.container.ModuleFederationPlugin({
name: 'host', // 主应用名称
exposes: {
'./Button': './src/Button', // 暴露 src/Button 模块
},
shared: ['react', 'react-dom'], // 公共依赖,避免重复加载
}),
],
};
2. 远程应用加载模块
在远程应用的 Webpack 配置中,你可以使用 remotes 来指定要加载的模块(即远程应用的模块)。
// webpack.config.js for remote (远程应用)
module.exports = {
plugins: [
new webpack.container.ModuleFederationPlugin({
name: 'remote', // 远程应用名称
remotes: {
host: 'host@http://localhost:3000/remoteEntry.js', // 从主应用加载模块
},
shared: ['react', 'react-dom'], // 公共依赖
}),
],
};
3. 加载和使用共享模块
在应用中,你可以直接加载和使用远程暴露的模块:
// 远程应用中动态加载主应用暴露的模块
import('host/Button').then(Button => {
const button = new Button();
document.body.appendChild(button.render());
});
4. 公共依赖共享
使用 shared 选项,可以在多个应用之间共享一些公共依赖(如 react, lodash 等),避免每个应用重复打包和加载相同的库。
// webpack.config.js
new webpack.container.ModuleFederationPlugin({
name: 'app',
remotes: {
otherApp: 'otherApp@http://localhost:3001/remoteEntry.js',
},
shared: {
react: { singleton: true }, // 共享 React,保证只有一个实例
'react-dom': { singleton: true },
},
});
优点
-
减少重复代码:
- 在微前端应用中,多个子应用可以共享同一个依赖,而无需每个应用单独打包,从而减少了冗余代码和流量。
-
提高性能:
- 共享模块可以在首次加载时加载一次,后续直接从缓存加载,避免重复下载和加载相同的资源。
-
支持动态加载:
- 远程模块可以按需动态加载,减少了初始页面加载的体积。
-
解耦独立部署:
- 每个应用可以独立开发和部署,只需要确保共享的模块版本兼容。不同团队可以独立开发和发布应用,而无需依赖于其他应用的发布周期。
缺点
-
配置复杂:
- 虽然 Webpack 提供了强大的功能,但是配置比较复杂,特别是在涉及多个应用和共享模块时,需要精心设计和管理模块和依赖。
-
版本管理问题:
- 共享模块时,必须管理好版本依赖,确保不同应用之间共享的模块版本兼容。否则可能会遇到版本冲突或不兼容的问题。
-
调试难度:
- 动态加载和远程应用的调试可能会比单一构建的应用更困难,尤其是多个应用间的状态和资源管理。
总结
Webpack 的 Module Federation 是一个强大的功能,特别适用于微前端架构和大型应用的模块化。通过模块联邦,可以让不同的应用或子应用共享代码和依赖,从而提升性能,减少冗余,并使得各个团队能够独立开发和发布自己的模块。
作者:千度麒麟
链接:juejin.cn/spost/72896…
来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。