likes
comments
collection
share

Webpack Module Federation 实践方案架构设计

作者站长头像
站长
· 阅读数 11

官方文档

背景

多个项目之间共享模块现在有这几种方式:

  • 共享模块打包成 npm 包,每个项目引入依赖
  • 每个项目打包时配置 external,通过 CDN 引入依赖
  • 共享模块使用 DLLPlugin 编译成公共包,每个项目单独修改 webpack 配置适配依赖

痛点:

  • 共享模块发布新版本(例如 BugFix),所有使用方项目都需要修改依赖,之后走一遍上线流程,流程较长,线上问题响应处理较慢;
  • npm公共组件库越维护越大,同时维护的人员众多,技术参差不齐,所以会趋于混乱。降低公共组件库的轻量性和稳定性;

Module Federation

webpack5 新特性

设计初衷

多个独立的构建可以组成一个应用程序,这些独立的构建之间不应该存在依赖关系,因此可以单独开发和部署它们。这通常被称作微前端,但并不仅限于此。

优缺点:

Module Federation」使 JavaScript 应用可以动态运行另一个 JavaScript 应用中的代码,同时可以共享依赖。

优点:

  • 颗粒度掌控自由,可以是小的组件、页面,也可以是大的应用或者SDK;
  • 模块即服务,模块的提供方方便维护,使用方也会降低很多维护成本;
  • 发布升级版本,使用者无需重新部署应用,只需生产者,组件提供方发版即可;
  • 共享模块非常灵活,模块中所有组件都可以通过异步加载调用,动态加载模块对性能提升有好处;

缺点:

  • 对环境要求略高,需要使用webpack5,旧项目改造成本大。
  • webpack为了支持加载remote模块对runtime做了大量改造,在运行时要做的事情也因此陡然增加,可能会对我们页面的运行时性能造成负面影响。

方案设计

模块共享模型备注说明:

  • biz A : 业务A
  • biz B : 业务B
  • modules: 公共基础模块库
  • module a : 业务A下的一个模块,通过模块共享出去
  • module b: 业务B下的一个模块,通过模块共享出去
  • module c : 公共基础模块库中的一个模块。

源站方案

优点:

  • 跟随项目一起发布,无需单独发布

缺点:

  • 随着共享模块的使用方增多,源站的压力越来越大。
  • 使用方收到源站部署升级的影响。
  • 源站的域名比较多,使用起来不同的源站,不同的环境域名维护混乱。

Webpack Module Federation 实践方案架构设计

CDN方案设计

所有共享出来的的远程模块(remote module)上传CDN,通过CDN地址访问,优缺点如下

优点

  • 提高访问速度
  • 减低模块提供方源站压力
  • 减少模块提供方各种域名维护,统一CDN域名。
  • 方便版本环境等功能管理。

缺点

  • 需要单独部署上传到CDN,(可以通过和部署额CICD结合来解决);

Webpack Module Federation 实践方案架构设计

请求remote module请求CDN地址,兜底请求源站地址,工作模型如下:

Webpack Module Federation 实践方案架构设计

CDN方案具体实现

思考: 这个原本的设计理念是一种P2P的思想,不应该是中心化的模式

实现思路: 通过接口配置的方式,下发远程入口地址和共享模块信息,页面动态加载渲染远程。 共享模块升级通过上传到CDN并更新接口远程模块信息来实现升级,消费者无需重新部署。

// new ModuleFederationPlugin({
//     name: 'webpackone',
//     filename: 'webpackone_v0_0_2.js',
//     exposes: {
//         './Custom': './src/pages/custom/index.jsx',
//         './OneInfo': './src/pages/oneInfo/index.jsx',
//     },
//     remotes: {
//        webpacktwo: "webpacktwo@https://timesky.top/webpack-mf-two/webpacktwo_v0_0_1.js",
//     },
// }),

// 在消费者方即使用爱方,远程模块信息通过接口配置,升级更新url地址来实现环境版本控制
[
    {
        "url":"https://timesky.top/webpack-mf-one/webpackone_v0_0_1.js",
        "scope":"webpackone",
        "module":"./OneInfo",
        "title":"业务系统A共享模块"
    },{
        "url":"https://timesky.top/webpack-mf-two/webpacktwo_v0_0_1.js",
        "scope":"webpacktwo",
        "module":"./TwoInfo",
        "title":"业务系统B共享模块"
    },{
        "url":"https://timesky.top/webpack-mf-one/webpackone_v0_0_1.js",
        "scope":"webpackone",
        "module":"./Custom",
        "title":"自定义模块"
    }
]

页面中通过加载配置信息渲染共享模块

Webpack Module Federation 实践方案架构设计

Webpack Module Federation 实践方案架构设计

Webpack Module Federation 实践方案架构设计

第一次加载的时候会动态加载远程模块。

Webpack Module Federation 实践方案架构设计

升级版本控制

发布之后,通过修改接口版本信息实现版本精确控制及版本回退;升级之后在源站验证通过之后再修改接口到CDN提供给所有的消费者使用。

消费者无需发布升级,接口更新实现了组价的版本动态升级。

Webpack Module Federation 实践方案架构设计

整体工作流程设计

工作流程如下图所示:

其中打包部署这块待继续调研

Webpack Module Federation 实践方案架构设计