EMP打破React版本枷锁,实现企业级微前端应用

455 阅读4分钟

背景

随着React19已经是stable的状态、很快会大面积投放使用,而且带来很多便捷与先进的开发方式以及新功能、新特征为开发效率赋能,但是项目的历史版本问题也是行业共同问题

一方面想用新技术,一方面也要兼顾老项目和历史问题,特别在微前端的应用上面更为明显,目前主流的做法都是React 17、18、19三个版本同时并存来加载运行应用,确保代码能正常执行

推演

为了解决上述问题、要进一步剥离框架所带来的影响如:

  • React框架以及会影响代码正常运行的附属内容
  • Module Federation Runtime & SDK
  • React 目前对代码的向下兼容能力比较乐观、很多老方法都保留了下来,对团队业务开发来说影响不大
  • 实现 3层架构对项目的灵活度、微前端轻量化来说是最有效的方案

image.png

@empjs/share 从创建到实现经历了 3 代的迭代分别为

  • [1.0] module federation shared
  • [2.0] emp shared library
  • [2.5] emp fast mode、emp runtime
  • [3.0] empShare 实现跨框架的同时、兼容了之前所有版本的共享模型,并且收归了共享所需的所有内容

随着时间推移、目前前两代的共享模型已经处于落后的状态,不能很好做依赖共享的配置,实现跨框架共享难度大,共享管理存在黑盒子问题难以追踪

随着新技术的引入,3.0 就以上的问题已经得到很好的解决,目前存在以下几个问题(优先级正序):

  • 类型共享存在不确定性
  • Runtime 模型缺乏指导性封装与应用,需要提供系统化教程
  • 需要把已打造好的案例模板化,系统化输出

EMP FastMode

EMP FastMode是我们2024年6月基于Module federation v2重新设计的新的共享模式,fastMode,进一步的把runtime、SDK从产物上剥离出来,减少框架对业务层的影响

对比起简单的Module Federation Shared,在EMP3启动项目之中,使用FastMode后能让启动项目构建后包体积减少76%,模块索引体积减少74%

image.png

FastMode比传统Module Federation Shared包体积小的原因是,FastMode 提取公共依赖到EMPShareLib,并进一步把远程模块公共运行时依赖的module-federation/runtime与sdk提取出来。从而实现加载提效

当然目前 Module federation 团队也意识到这个问题、在最新版本也开始陆续解决这些问题 externalruntime

实战

EMP v3.5 & @empjs/share

文档使用参考 link image.png

3.5 在上述基础上把 React的所有依赖也抽离业务 从而实现 业务与框架的完全分离

image.png

代码片段

import {defineConfig} from '@empjs/cli'
import pluginReact from '@empjs/plugin-react'
import {pluginRspackEmpShare} from '@empjs/share/rspack'
export default defineConfig(store => {
  const reactVersion = 19
  return {
    plugins: [
      pluginReact({
        version: reactVersion,
      }),
      pluginRspackEmpShare({
        // module federation runtime & sdk 配置 基于 0.6.10 小部分重构 支持external
        empRuntime: {
          runtime: {
            lib: `https://yourcdn.com/@empjs/share@3.5.0/output/sdk.js`,
          },
          // 框架以umd格式暴露
          framework: {
            name: 'react',
            version: reactVersion,
            // 最终访问地址 默认为 reactRouter.development.umd.js
            entry: 'reactRouter',
            global: 'EMP_ADAPTER_REACT',
            // 自动区分 dev & prod
            lib: `https://yourcdn.com/@empjs/react@${reactVersion}/dist`,
          },
        },
      }),
    ],
  }
})

实际效果代码如下

image.png

可以clone 下来运行 emp dev 观看结果:

图中我们看到

  • 导航分别代表了3个React项目,分布到17~19的版本
  • 切换导航,表示独立运行到相应的版本,而且正常运行
  • 中间两个是独立的远程组件
  • 在微前端、低代码的业务环境中,多版本远程组件是一个必不可少的功能,方案可以很好实现

结论

通过以上方案、我们可以实现:

  • 1 项目不断开展的情况下可以无缝 React的框架升级而不影响现有业务的正常运行
  • 2 运行代码最小化原则,只涵盖了最基本的业务代码,服务最优选择
  • 3 代码维护成本直线降低,更适合微前端的落地 (构建时候各个版本会有部分差异性代码存在,此方案很好解决这个问题)