前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >微前端模块共享你真的懂了吗

微前端模块共享你真的懂了吗

作者头像
树酱
发布2022-03-08 14:21:14
2.7K0
发布2022-03-08 14:21:14
举报
文章被收录于专栏:前端那些趣事

前言:我们运用微前端架构解决了应用体积庞大的问题,通过实践微前端的理念,将前端应用拆分为多个微应用(可独立部署、松散耦合的应用)。同时微应用的存在,使得我们无需在构建一个庞大的应用,而是按需构建,极大了加快了构建效率。但只是解决了应用层面的问题,在中后台应用场景中,不同微应用和基座之间可能存在通用的模块依赖,那么如果应用间可以实现模块共享,那么可以大大优化单应体积大小

1.Npm 依赖

最简单的方式,就是把需要共享的模块抽出,可能是一个工具库,有可能是一个组件库,然后讲其打包成为npm包,然后在每个子应用中都安装该模块依赖,以此达到多个项目复用的效果

也就代表每个应用都有相同的npm包,本质上没有真正意义上的实现模块共享和复用,只是代码层次共享和复用了,应用打包构建时,还是会将依赖包一起打包

劣势有以下👇 几点:

  • 每个微应用都会打包该模块,导致依赖的包冗余,没有真正意义上的共享复用
  • npm包进行更新发布了,微应用还需要重新构建,调试麻烦且低效 (除非用npm link

2.Git Submodule (子模块)

阿乐童鞋: 那如果我们没有搭建npm内网,又不想把模块开源出去,而且依赖npm,只要涉及变更需要重新发布,有没有其他方式可以解决以上问题呀?

2.1 对比 npm

你可以试试 Git Submodule ,它提供了一种类似于npm package的依赖管理机制,两者差别如下图所示👇

2.2 如何使用

通过在应用项目中,通过git submodule add <submodule_url>远程拉取子模块项目,这时会发现应用项目中多了两个文件.gitmodules子模块目录

这个子模块就是我们共享的模块,它是一个完整的Git仓库,换句话说:我们在应用项目目录中无论使用git add/commit都对其不影响,即子模块拥有自身独立的版本控制

总结: submodule本质上是通过git submodule add把项目依赖的模块加起来,最终构成一个完整的项目。而且add进来的模块,项目中并不实际包含,而只是一个包含索引信息,也就是上文提到的 .gitmodule来存储子模块的联系方式, 以此实现同步关联子模块。当下载到本地运行的时候才会再拉取文件

部分命令行:

  • git submodule add <子模块repository> <path> : 添加子模块
  • git submodule update --recursive --remote : 拉取所有子模块的更新
2.3 Monorepo

阿乐童鞋: 🌲 树酱,我记得有个叫Monorepo又是什么玩意,跟 Git Submodule 有啥区别?

Monorepo 全称叫monolithic respoitory,即单体式仓库,核心是允许我们将多个项目放到同一个仓库里面进行管理。主张不拆分repo,而是在单仓库里统一管理各个模块的构建流程、版本号等等

这样可以避免大量的冗余node_module冗余,因为每个项目都会安装vue、vue-router等包,再或者本地开发需要的webpack、babel、mock等都会造成储存空间的浪费

那么Monorepo是怎么管理的呢? 开源社区中诸如babel、vue的项目都是基于Monorepo去维护的(Lerna工具)

我们以Babel为例,在github中可以看到其每个模块都在指定的packages目录下, 也就意味着将所有的相关package都放入一个repository来管理,这不是显得项目很臃肿?

也就这个问题,啊乐同学和啊康同学展开了辩论~

最终是选用Monorepo单体式仓库还是Multirepo多仓库管理, 具体还是要看你业务场景来定,Monorepo集中管理带来的便利性,比如方便版本、依赖等管理、方便调试,但也带来了不少不便之处 👇

  • 统一构建工具所带来更高的要求
  • 仓库体积过大,维护成本也高

🌲 酱 不小心扯多了,还有就是Monorepo 跟 Git Submodule 的区别

  • 前者:monorepo在单repo里存放所有子模块源码
  • 后者:submodules只在主repo里存放所有子模块“索引”

目前内部还未使用Monorepo进行落地实际,目前基于微前端架构中后台应用存在依赖重叠过多的情况,后期会通过实践来深入分享

3. Webpack external

我们知道webpack中有externals的配置,主要是用来配置:webpack输出的bundle中排除依赖,换句话说通过在external定义的依赖,最终输出的bundle不存在该依赖,主要适用于不需要经常打包更新的第三方依赖,以此来实现模块共享。

下面是一个vue.config.js 的配置文件,通过配置exteral移除不经常更新打包的第三方依赖👇

你可以通过在packjson中script定义的命令后添加--report查看打包📦后的分析图,如果是webpack就是用使用插件webpack-bundle-analyzer

阿乐童鞋: 🌲 树酱,那移除了这些依赖之后,如何保证应用正常使用?

浏览器环境:我们使用cdn的方式在入口文件引入,当然你也可以预先打包好,比如把vue全家桶打包成vue-family.min.js文件,最终达成多应用共享模块的效果

<script src="<%= VUE_APP_UTILS_URL %>static/js/vue-family.min.js"></script>

总结:避免公共模块包(package) 一起打到bundle 中,而是在运行时再去从外部获取这些扩展依赖

通过这种形式在微前端基座应用加载公共模块,并将微应用引用同样模块的external移除掉,就可以实现模块共享了 但是存在微应用技术栈多样化不统一的情况,可能有的使用vue3,有的使用react开发,但externals 并无法支持多版本共存的情况,针对这种情况该方式就不太适用

4. Webpack DLL

官方介绍:"DLL" 一词代表微软最初引入的动态链接库, 换句话说我的理解,可以把它当做缓存,通过预先编译好的第三方外部依赖bundle,来节省应用在打包时混入的时间

Webpack DLL 跟 上一节提到的external本质是解决同样的问题:就是避免将第三方外部依赖打入到应用的bundle中(业务代码),然后在运行时再去加载这部分依赖,以此来实现模块复用,也提升了编译构建速度

webpack dll模式下需要配置两份webpack配置,下面是主要两个核心插件

4.1 DllPlugin

DllPlugin:在一个独立的webpack进行配置webpack.dll.config.js,目的是为了创建一个把所有的第三方库依赖打包到一起的bundle的dll文件里面,同时还会生成一个manifest.json的文件,用于:让使用该第三方依赖集合的应用配置的DllReferencePlugin能映射到相关的依赖上去 具体配置看下图👇

4.2 DllReferencePlugin

DllReferencePlugin:插件核心是把上一节提到的通过webpack.dll.config.js中打包生成的dll文件,引用到需要实际项目中使用,引用机制就是通过DllReferencePlugin插件来读取vendor-manifest.json文件,看看是否有该第三方库,最后通过add-asset-html-webpack-plugin插件在入口html自动插入上一节生成的vendor.dll.js 文件, 具体配置看下图👇

5. 联邦模块 Module Federation

模块联邦是 Webpack5 推出的一个新的重要功能,可以真正意义上实现让跨应用间做到模块共享,解决了从前用 NPM 公共包方式共享的不便利,同时也可以作为微前端的落地方案,完美秒杀了上两节介绍webpack特征

用过qiankun的小伙伴应该知道,qiankun微前端架构控制的粒度是在应用层面,而Module Federation控制的粒度是在模块层面。相比之下,后者粒度更小,可以有更多的选择

与qiankun等微前端架构不同的另一点是,我们一般都是需要一个中心基座去控制微应用的生命周期,而Module Federation则是去中心化的,没有中心基座的概念,每一个模块或者应用都是可以导入或导出,我们可以称为:host和remote,应用或模块即可以是host也可以是remote,亦或者两者共同体

看看下面这个例子👇

核心在于 ModuleFederationPlugin中的几个属性

  • remote : 示作为 Host 时,去消费哪些 Remote;
  • exposes :表示作为 Remote 时,export 哪些属性提供给 Host 消费
  • shared: 可以让远程加载的模块对应依赖改为使用本地项目的 vue,换句话说优先用 Host 的依赖,如果 Host 没有,最后再使用自己的

后期也会围绕 Module Federation 去做落地分享

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2021/07/14 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1.Npm 依赖
  • 2.Git Submodule (子模块)
    • 2.1 对比 npm
      • 2.2 如何使用
        • 2.3 Monorepo
        • 3. Webpack external
        • 4. Webpack DLL
          • 4.1 DllPlugin
            • 4.2 DllReferencePlugin
            • 5. 联邦模块 Module Federation
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档