背景
多个项目之间共享模块现在有这几种方式:
- 共享模块打包成 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 : 公共基础模块库中的一个模块。
源站方案
优点:
- 跟随项目一起发布,无需单独发布
缺点:
- 随着共享模块的使用方增多,源站的压力越来越大。
- 使用方收到源站部署升级的影响。
- 源站的域名比较多,使用起来不同的源站,不同的环境域名维护混乱。
CDN方案设计
所有共享出来的的远程模块(remote module)上传CDN,通过CDN地址访问,优缺点如下
优点
- 提高访问速度
- 减低模块提供方源站压力
- 减少模块提供方各种域名维护,统一CDN域名。
- 方便版本环境等功能管理。
缺点
- 需要单独部署上传到CDN,(可以通过和部署额CICD结合来解决);
请求remote module请求CDN地址,兜底请求源站地址,工作模型如下:
CDN方案具体实现
思考: 这个原本的设计理念是一种P2P的思想,不应该是中心化的模式
实现思路: 通过接口配置的方式,下发远程入口地址和共享模块信息,页面动态加载渲染远程。 共享模块升级通过上传到CDN并更新接口远程模块信息来实现升级,消费者无需重新部署。
js
// 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":"自定义模块"
}
]
页面中通过加载配置信息渲染共享模块
第一次加载的时候会动态加载远程模块。
升级版本控制
发布之后,通过修改接口版本信息实现版本精确控制及版本回退;升级之后在源站验证通过之后再修改接口到CDN提供给所有的消费者使用。
消费者无需发布升级,接口更新实现了组价的版本动态升级。
整体工作流程设计
工作流程如下图所示:
其中打包部署这块待继续调研