WPM(web package manager)
wpm(web package manager)是一个微前端包管理平台, 在公司内使用, 目前仅开源了部分插件在下文介绍。
MF介绍
webpack5 module-federation很强大, 使前端的代码(模块)共享达到了一个新等级, 可以像使用本地模块一样使用远程代码
在这之前, 必然是使用最为广泛标准的UMD模块规范来做共享, 使用systemjs等加载器需要处理promise逻辑, 仅在使用异步组件时影响较小, 若远程模块是个函数、是个配置项(如JSON数据), 那么使用限制便会比较明显, 并且也没有成熟配套的TS提示等开发环境支持。
MF能够接近无感知的使用远程模块, 并在各领域都有解决方案(webpack-4、5、vite/rollup、TS、SSR、medusa/dashboard等), 比需要人为编码来异步处理远程模块更加高效和稳定
MF增强
公司有数百个微前端应用、模块, 并且公司的业务架构也会需要大量的产品融合组件(不同的业务互相提供能力、提供组件), 与MF的特性极为契合。
那么直接使用MF会有什么问题?
- 数百个微前端项目, 需要全量升级, 适配(如果有团队使用webpack5提供一个MF模块, webpack4的团队无法消费此模块)
- 现存大量远程模块, 如何复用而不重构(升级mf后, 远程资源分为两种(1.UMD 2.MF), 两种远程模块都会有依赖项, 两种依赖需要能互通, 能保持单例)
对于以上两个问题, 我们提供了两个开源项目分别为对应解决方案, 并提高了module-federation的通用性, 不再受限于webpack5(module-federation/webpack-4), 支持集成其他模块规范(universal-module-federation)。
有了这两个插件的支持, 甚至可以将MF当作一个同步加载远程的通用模块加载器, 并在现有的项目中可以直接使用, 理应也能复用MF的ts、dashboard/medusa等原有生态。
如何支持多版本共存:
可能会有很多人会认为, MF的remote无法多版本共存, 首先这不是MF的缺点, 也并非无解。
- 由于webpack应用需要在window挂载全局变量, 使用jsonp加载不同的chunk。而MF也有一个全局唯一的模块名会污染全局空间, 在同一个应用多个版本同时出现时, 全局模块会发生冲突。
- 只需要在webpack的配置项, output.library.[name | uniqueName]、ModuleFederationOptions.name 中加上版本号的维度, 全局冲突即可解决(由于全局jsonp变量名会出现在所有chunk中, 所以此种设置每个版本的打包所有chunk的hash都会变化, 缓存会失效, 但一般无需多版本)。
多版本弊端:
- 同一个remote多个版本同时被加载, 在H5环境不应该存在, 多版本的出现会增加网络请求的资源, 造成性能问题
- 在B端大型微前端项目, 大概率会需要remote共存多个版本, 但与H5同理, 一般是跨微前端应用才会出现, 同一个应用也仍然需要保证版本统一, 不请求多余资源来保证加载速度。而跨应用有qiankun之类的微前端解决方案来隔离window全局变量, 此问题也不复存在。
未来升级:
如果webpack淘汰, MF项目能否不重构继续使用
- 如果turbopack继任webpack, MF官方将会继续支持
- 如果其他构建工具继任webpack, 也能够做到让MF项目继续能跑, 可参考usemf(在其他环境加载MF模块), 并且在这过程之中, 也一定会有类似的技术产生。
- 即使到了可以直接在浏览器使用esmodule的时代, 直接引入原有MF的模块文件, 也可以promise形式使用, 但届时可以简化打包流程, 直接输出ES模块来支持。
所以, 未来无论前端生态怎么改变, 总可以有平滑升级的方案, 但是我们需要向开源生态靠拢, 以免未来只能重构。