微前端父子应用及兄弟应用间组件或方法共享方案

京东云开发者
• 阅读 367

背景

我们的很多web应用在持续迭代中功能越来越复杂,参与的人员、团队不断增多,导致项目出现难以维护的问题,这种情况PC端尤其常见,微前端为我们提供了一种高效管理复杂应用的方案。但是在使用微前端的过程中,通常会有一些公共方法或公共组件,本文将对如何实现父子应用以及兄弟应用之间进行方法及组件共享提出几种解决方案以及其各自优缺点及适用场景

模块联邦(Module Federation)

webpack5引入了模块联邦,可以让不同的应用共享模块。具体步骤如下:

Remote(提供者模块)

    // webpack.config.js
    module.exports = {
        // 其他配置...
        plugins: [
            new ModuleFederationPlugin({
            name: 'component_app',
            filename: 'remoteEntry.js',
            exposes: {
                './Button': './src/Button.jsx',
                './Dialog': './src/Dialog.jsx',
                './Logo': './src/Logo.jsx',
                './ToolTip': './src/ToolTip.jsx',
            },
            shared: { react: { singleton: true }, 'react-dom': { singleton: true } },
            }),
        ],
    };

作为提供方,component 将自己的 Button、Dialog等组件暴露出去,同时将 react 和 react-dom 这两个依赖共享出去。

host(使用者模块)

    // webpack.config.js
    module.exports = {
        entry: './index.js',
        // ...
        plugins: [
            new ModuleFederationPlugin({
            name: 'main_app',
            //远程访问地址入口 
            remotes: {
                'component-app': 'component_app@http://localhost:3001/remoteEntry.js',
            },
            shared: { react: { singleton: true }, 'react-dom': { singleton: true } },
            })
        ],
    };

作为消费者的 main 应用需要定义需要消费的应用的名称以及地址,同时 main 应用也将自己的 react 和 react-dom 这两个依赖共享出去。

通过以上方式可以实现不同应用之间共享公共方法和组件,虽然vite本身不支持模块联邦,但是我们可以使用vite-plugin-federation这个插件。
优点

  1. 代码共享:不同的微应用可以共享相同的依赖库,减少重复下载和加载,提高性能。
  2. 独立部署:各个微应用可以独立开发、测试和部署,减少了团队之间的耦合,提高了开发效率。
  3. 动态加载:可以在运行时动态加载模块,按需加载,减少初始加载时间。
  4. 版本控制:支持不同版本的模块共存,解决了版本冲突的问题。
  5. 团队协作:各个团队可以独立开发自己的模块,减少了对中央仓库的依赖,提高了协作效率。

缺点

  1. 对于webpack5以下的应用不支持
  2. 复杂性增加:配置和管理模块联邦需要一定的学习成本和经验,增加了项目的复杂性。
  3. 调试困难:由于模块是动态加载的,调试和追踪问题可能会变得更加困难。
  4. 性能开销:虽然减少了初始加载时间,但动态加载模块可能会在运行时引入额外的性能开销。
  5. 依赖管理:需要仔细管理共享依赖的版本,避免潜在的兼容性问题。
  6. 安全性:动态加载外部模块可能会引入安全风险,需要额外的安全措施来防止恶意代码注入。

NPM包

将共享组件打包成一个 NPM 包,然后在父子应用中分别安装和使用。

  1. 创建共享组件/方法库

    import React from 'react';
    const SharedComponent = () => <div>Shared Component</div>;
    export default SharedComponent;
  2. 发布到NPM

    npm publish
  3. 在父应用和子应用中安装

    npm install shared-component-library
  4. 在应用中使用

     import SharedComponent from 'shared-component-library';
    
     function App() {
     return ;
     }
    
     export default App;

优点

  1. 模块化管理:通过npm包管理公共组件,可以实现模块化开发,便于维护和更新。
  2. 版本控制:npm包自带版本控制功能,可以方便地进行版本管理,确保不同微应用使用兼容的组件版本。
  3. 依赖管理:npm包可以自动管理依赖关系,减少手动处理依赖的复杂性。
  4. 复用性高:公共组件封装成npm包后,可以在多个微应用中复用,减少重复开发,提高开发效率。
  5. 社区支持:npm生态系统庞大,很多问题可以通过社区资源解决,减少开发难度。

缺点

  1. 发布和更新成本:每次更新公共组件都需要重新发布npm包,并在各个微应用中更新依赖,增加了一定的工作量。
  2. 版本兼容性问题:不同微应用可能对同一组件有不同的版本需求,处理版本兼容性问题可能会比较复杂。
  3. 性能开销:由于npm包需要通过网络下载和安装,可能会增加构建时间和初始加载时间。
  4. 调试复杂性:npm包作为独立模块,调试时可能需要额外的配置和步骤,增加了调试的复杂性。
  5. 安全性问题:使用第三方npm包时,需要注意其安全性,防止引入潜在的安全漏洞。

使用 CDN

将共享组件打包并上传到 CDN,然后在父子应用中通过 URL 引入。

  1. 打包共享组件:

    npm run build
  2. 上传到 CDN。

  3. 在应用中引入:

    <script src="https://cdn.example.com/shared-component.js"></script>
    // 假设共享组件暴露为全局变量 SharedComponent
    function App() {
      return <SharedComponent />;
    }
    export default App;

优点

  1. 性能提升:

    • 快速加载:CDN 服务器分布在全球各地,用户可以从最近的服务器获取资源,从而减少加载时间。
    • 缓存机制:CDN 提供了强大的缓存机制,可以减少服务器的负载,提高响应速度。
  2. 带宽优化:

    • 减轻服务器压力:通过将静态资源托管在 CDN 上,可以减轻原始服务器的带宽压力。
    • 分布式传输:CDN 可以将流量分散到多个节点,避免单点瓶颈。
  3. 高可用性:

    • 冗余备份:CDN 通常有多个备份节点,即使某个节点出现故障,其他节点也能继续提供服务。
    • 自动故障切换:CDN 能够自动检测并切换到可用的节点,确保服务的连续性。
  4. 版本管理:

    • 统一管理:通过 CDN 可以统一管理公共组件的版本,确保所有微应用使用相同的组件版本,减少兼容性问题。

缺点

  1. 安全性问题:依赖第三方:使用第三方 CDN 服务可能会带来安全隐患,特别是如果 CDN 提供商遭到攻击或出现故障。

  2. 缓存一致性:

    • 缓存更新延迟:CDN 的缓存机制可能导致更新的资源不能及时传播到所有节点,造成版本不一致的问题。
    • 缓存失效:需要手动管理缓存失效策略,否则可能会导致旧版本资源被长期缓存。
  3. 依赖性:

    • 网络依赖:如果用户的网络环境较差,可能会影响到通过 CDN 获取资源的速度和稳定性。
    • 服务依赖:过度依赖 CDN 可能会导致在 CDN 服务出现问题时,整个应用的可用性受到影响。

使用 iframe

如果组件之间的交互较少,可以考虑使用 iframe 嵌入子应用。
在父应用中嵌入 iframe:

<iframe src="http://localhost:3001" width="100%" height="500px"></iframe>

优点

  1. 隔离性强:iframe 提供了一个独立的浏览上下文,能够有效隔离不同微应用之间的样式和脚本,避免相互干扰。
  2. 安全性高:由于 iframe 的隔离特性,能够防止跨站脚本攻击(XSS)和其他安全问题。
  3. 兼容性好:iframe 是浏览器原生支持的技术,兼容性较好,能够在大多数现代浏览器中正常工作。
  4. 独立部署:各个微应用可以独立部署和更新,不需要担心对其他应用的影响。

缺点

  1. 性能问题:iframe 会增加页面的加载时间和内存消耗,尤其是在嵌套多个 iframe 的情况下。
  2. 通信复杂:iframe 与父页面之间的通信需要通过 postMessage 等机制实现,增加了开发的复杂性。
  3. SEO 不友好:搜索引擎对 iframe 内容的抓取和索引支持较差,可能影响 SEO 效果。
  4. 样式和布局问题:iframe 的内容与父页面的样式和布局是独立的,可能需要额外的工作来确保一致性。
  5. 调试困难:iframe 内部的调试相对复杂,尤其是在跨域的情况下,调试工具的使用会受到限制。

总结

不同的方案有各自的特点,需要根据具体的应用场景和需求进行权衡。

点赞
收藏
评论区
推荐文章
徐小夕 徐小夕
3年前
微前端架构初探以及我的前端技术盘点
前言最近几年微前端一直是前端界的热门议题,它类似于微服务架构,主要面向于浏览器端,能将一个复杂而庞大的单体应用拆分为多个功能模块清晰且独立的子应用,且共同服于务同一个主应用。各个子应用可以独立运行、独立开发和独立部署。微前端架构概念的诞生及应用对于提供复杂应用服务的企业来说显然是一种机遇,同样也是一种挑战.本文主要就微前端架构的概念和实现方案做一
漫谈前端自动化测试演进之路及测试工具分析
随着前端技术的不断发展和应用程序的日益复杂,前端自动化测试也在不断演进。随着Web应用程序变得越来越复杂,自动化测试的需求也越来越高。如今,自动化测试已经成为Web应用程序开发过程中不可或缺的一部分,它们可以帮助开发人员更快地发现和修复错误,提高应用程序的性能和可靠性。
Stella981 Stella981
3年前
React 世界的一等公民
Choerodon猪齿鱼平台使用React作为前端应用框架,对前端的展示做了一定的封装和处理,并配套提供了前端组件库ChoerodonUI。结合实际业务情况,不断对组件优化设计,提高代码质量。本文将结合Choerodon猪齿鱼平台使用案例,简单说明组件的分类、设计原则和设计模式,帮助开发者在不同场景下选择正确的设计和方案编写组件(示例代码基于ES6
京东云开发者 京东云开发者
4个月前
微前端父子应用及兄弟应用间组件或方法共享方案
背景我们的很多web应用在持续迭代中功能越来越复杂,参与的人员、团队不断增多,导致项目出现难以维护的问题,这种情况PC端尤其常见,微前端为我们提供了一种高效管理复杂应用的方案。但是在使用微前端的过程中,通常会有一些公共方法或公共组件,本文将对如何实现父子应
微前端无界机制浅析 | 京东物流技术团队
简介随着项目的发展,前端SPA应用的规模不断加大、业务代码耦合、编译慢,导致日常的维护难度日益增加。同时前端技术的发展迅猛,导致功能扩展吃力,重构成本高,稳定性低。为了能够将前端模块解耦,通过相关技术调研,最终选择了无界微前端框架作为物流客服系统解耦支持。
爱学it学无止境 爱学it学无止境
4个月前
Vue3 + TS 仿知乎专栏企业级项目完结
Vue3TypeScript:打造高效、可靠的现代前端应用在快速迭代的前端开发领域,Vue.js3与TypeScript(TS)的结合已成为构建高效、可靠且易于维护的现代Web应用的优选方案。Vue3以其轻量级、高性能和灵活的响应式系统著称,而TypeS
爱学it学无止境 爱学it学无止境
4个月前
高级前端进阶必修:自主打造高扩展的业务组件库无密分享
组件库:前端开发的基石与未来趋势在前端开发的广阔领域中,组件库作为一组预先设计好的、可重用的UI组件集合,已成为提升开发效率、保证项目一致性和可维护性的重要工具。本文将从组件库的定义、构建原则、应用场景及未来发展趋势等方面进行深入探讨,以期为前端开发者提供