利用webpack5实现代码的共享

在前端项目中经常遇到这种情况。

痛点:

随着企业的业务迅速铺开,项目数量越来越多,业务功能越来越复杂。几个小组并行开发会极大地提高开发效率,但稍不注意,就会出现几下几个问题:

相同、类似的功能,在一同项目中反复出现

为了迅速上线,将一个成熟的模块/功能,在不同的项目间copy

随着时间的流逝,一个小的改动就需要花大量人力工时,而且还易容出错,项目维护变得举步为艰。

。。。

要列的话可能还有其他问题。当然,也可以用一句话简单概括这些问题:

如何解决项目中、项目间代码/逻辑共享?

从前端架构上来看,目前市面上有两种相对比较成熟的解决方案:

NPM 方式共享模块

UMD 方式共享模块

这两个解决方案一方面门槛比较高,另一方面,它们解决问题的同时,也带来了另一些问题, 详情可参考 这里

近两三年,微前端的架构方兴未艾,也给我们提供了更多的选择,值得一提是qiankun 2.0这个微前端框架,在众多前端er 的打磨之下,已经越来越好用了。

qiankun甚至一度被认为是微前端的最佳解决方案。但用过的同学始终觉得这种共享模式不够优雅,如果再算上由此带来的项目改造成本,和构建成本,那就更是吃力了。

好在这个时候  webpack5 来了,它给我们带来了Module Federation

webpack5 的 Module Federation, 以下间称MF,为我们提供了在应用间共享代码的新选项,让我们优雅地实现微前端架构。

有了MF我们不需要对我们现有的项目做调整和改动,也不需要忍受 NPM\UMD方式带来的负面效果,我们只需要在 webpack的配文件中引入ModuleFederationPlugin,做好相应的配置就好了。

MF原理大概是这样的:

MF 允许我们直接将一个应用的包应用于另一个应用,同时具备整体应用一起打包的公共依赖抽取能力。

比如A应用由1,2,3模块组合而成,而B应用也需要用到1,2模块,而模块1,2应用到B应用,无需在B应用中安装、编译、集成,可以直接复用A应用的相关模块。

引用的1,2模块在A应用中就把相关的依赖都集成完成,直接引用接口,达到按需热插拔。

当然,真正企业中的项目可不止是两个,往往是很多个,在多个应用间相互共享的策略则应该是这样的:

所有子应用都可以利用 Runtime 方式复用主应用的 Npm 包和模块,更好的集成到主应用中。

MF让应用具备模块化输出能力,其实开辟了一种新的应用形态,即 “中心应用”,这个中心应用用于在线动态分发 Runtime 子模块,并不直接提供给用户使用。

先列出MF优势:

1.无需安装共享的组件 –  享受npm方式的带来的代码体积优化,又不用负担打包建的成本
2.运行时加载  – 组件即时更新,无版本升级的问题
3.按需加载热插拔  – 方便快捷,跟本地调用一样
4.Host与Remote双重身份  –  共享粒度可粗可细,精准控制共享模块

一句话: FM为我们提供了优雅的微前端实现方案。


下面我们就来 step by step 

用 MF 实现应用间的代码共享

1. 升级webpack到5。

wepapck5已经出来一年多了,早就不是bate版了,现在已经是稳定版了,放心大胆的用吧

2. run 一下项目,根据提示同步更新一下webpack.config.js里的配置

如果是从4升级到5,其实没什么要改的,但如果是从3升上来的,就比较麻烦,改 的东西比较多——怪谁,技术欠债自己还

3. 以下正式进入到MF配置:

假设我们有两个项目app1, 与remote, 看名字就知道我们要干嘛了

app1 的 webapck.config.js

用 const { ModuleFederationPlugin } = require("webpack").container; 引入我们的主角MF.
output 下的 publicPath是为MF作为生产者时对外的资源路径。
重头戏是plugin里的 new ModuleFederationPlugin
原来MF是作为插件在webpack里使用的~~

说明直接写到代码里,如上,所见即所得。

所以,MF的共享是双向的,它既可以导出组件给别人用(在exposes里配置),同时也可以使用别人导出来的组件(在remotes里配置),这本身就体现了微前端的思想。exposes为生产者,remotes为消费者,一个项目可以同时有这两个身份,也可以独居任何一个。
在初配的过程中需要注意一下, name(微前端里标识这个服务的唯一标识符),filename(最终给别人使用的文件我,常与publicPath, 一起用)

4. 使用其他项目提供的组件
我在app1里这样使用 remote导出来的 SayHi 组件:

这个是 remote里的 SayHi ——!

5. 注意项目的入口

我们需要在入口做一些改动,由于被共享的组件需要被先加载进来。但webpack在构建打包时,并不知道romote list 里哪些组件是被使用到的。于是,我们要在入口里动态加载我们的程序。

官方的说法是  我们强烈建议使用异步边界

当然,有一说一。 FM,稍有不足的是,里面有个 share的配制项,他要求多应用中所用的版本是一样的,也就是说如果是react, 就都用react。那么,微前端架构的 技术无关性,是怎样体现的呢?头痛 ——!

总之,我们拥抱变化吧~~

参考:

https://segmentfault.com/a/1190000024449390

https://zhuanlan.zhihu.com/p/115403616

你可能感兴趣的:(利用webpack5实现代码的共享)