Webpack5新特性之模块联邦
大家好,很高兴又见面了,我是"web 前端分享",由我带着大家一起关注前端前沿、深入前端底层技术,大家一起进步,也欢迎大家关注、点赞、收藏、转发! 1 引言
Webpack 5
先说结论:Webpack5 模块联邦让 Webpack 达到了线上 Runtime 的效果,让代码直接在项目间利用 CDN 直接共享,不再需要本地安装 Npm 包、构建再发布了!
我们知道 Webpack 可以通过 DLL 或者 Externals 做代码共享时 Common Chunk,但 不同应用和项目间 这个任务就变得困难了,我们几乎无法在项目之间做到按需热插拔。
模块联邦是 Webpack5 新内置的一个重要功能,可以让跨应用间真正做到模块共享,所以 这篇文章将带你了解什么是 "模块联邦" 功能。 2 概述 & 精读NPM 方式共享模块
想象一下正常的共享模块方式,对,就是 NPM。
如下图所示,正常的代码共享需要将依赖作为 Lib 安装到项目,进行 Webpack 打包构建再上线,如下图:
对于项目 Home 与 Search,需要共享一个模块时,最常见的办法就是将其抽成通用依赖并分别安装在各自项目中。
虽然 Monorepo 可以一定程度解决重复安装和修改困难的问题,但依然需要走本地编译。 UMD 方式共享模块
真正 Runtime 的方式可能是 UMD 方式共享代码模块,即将模块用 Webpack UMD 模式打包,并输出到其他项目中。这是非常普遍的模块共享方式:
对于项目 Home 与 Search,直接利用 UMD 包复用一个模块。但这种技术方案问题也很明显,就是包体积无法达到本地编译时的优化效果,且库之间容易冲突。 微前端方式共享模块
微前端:micro-frontends (MFE) 也是最近比较火的模块共享管理方式,微前端就是要解决多项目并存问题,多项目并存的最大问题就是模块共享,不能有冲突。
由于微前端还要考虑样式冲突、生命周期管理,所以本文只聚焦在资源加载方式上。微前端一般有两种打包方式: 子应用独立打包,模块更解耦,但无法抽取公共依赖等。 整体应用一起打包,很好解决上面的问题,但打包速度实在是太慢了,不具备水平扩展能力。 模块联邦方式
终于提到本文的主角了,作为 Webpack5 内置核心特性之一的 Federated Module:
从图中可以看到,这个方案是直接将一个应用的包应用于另一个应用,同时具备整体应用一起打包的公共依赖抽取能力。
让应用具备模块化输出能力,其实开辟了一种新的应用形态,即 "中心应用",这个中心应用用于在线动态分发 Runtime 子模块,并不直接提供给用户使用:
对微前端而言,这张图就是一个完美的主应用,因为所有子应用都可以利用 Runtime 方式复用主应用的 Npm 包和模块,更好的集成到主应用中。
模块联邦的使用方式如下: const HtmlWebpackPlugin = require("html-webpack-plugin"); const ModuleFederationPlugin = require("webpack/lib/container/ModuleFederationPlugin"); module.exports = { // other webpack configs... plugins: [ new ModuleFederationPlugin({ name: "app_one_remote", remotes: { app_two: "app_two_remote", app_three: "app_three_remote" }, exposes: { AppContainer: "./src/App" }, shared: ["react", "react-dom", "react-router-dom"] }), new HtmlWebpackPlugin({ template: "./public/index.html", chunks: ["main"] }) ] };
模块联邦本身是一个普通的 Webpack 插件 ModuleFederationPlugin,插件有几个重要参数: name 当前应用名称,需要全局唯一。 remotes 可以将其他项目的 name 映射到当前项目中。 exposes 表示导出的模块,只有在此申明的模块才可以作为远程依赖被使用。 shared 是非常重要的参数,指定了这个参数,可以让远程加载的模块对应依赖改为使用本地项目的 React 或 ReactDOM。
比如设置了 remotes: { app_two: "app_two_remote" },在代码中就可以直接利用以下方式直接从对方应用调用模块: import { Search } from "app_two/Search";
这个 app_two/Search 来自于 app_two 的配置: // app_two 的 webpack 配置 export default { plugins: [ new ModuleFederationPlugin({ name: "app_two", library: { type: "var", name: "app_two" }, filename: "remoteEntry.js", exposes: { Search: "./src/Search" }, shared: ["react", "react-dom"] }) ] };
正是因为 Search 在 exposes 被导出,我们因此可以使用 [name]/[exposes_name] 这个模块,这个模块对于被引用应用来说是一个本地模块。 3 总结
模块联邦为更大型的前端应用提供了开箱解决方案,并已经作为 Webpack5 官方模块内置,可以说是继 Externals 后最终的运行时代码复用解决方案。
另外 Webpack5 还内置了大量编译时缓存功能,可以看到,无论是性能还是多项目组织,Webpack5 都在尝试给出自己的最佳思路,期待 Webpack5 正式发布,前端工程化会迈向一个新的阶段。 参考资料
原文链接:https://github.com/ascoders/weekly/blob/master/%E5%89%8D%E6%B2%BF%E6%8A%80%E6%9C%AF/144.%E7%B2%BE%E8%AF%BB%E3%80%8AWebpack5%20%E6%96%B0%E7%89%B9%E6%80%A7%20-%20%E6%A8%A1%E5%9D%97%E8%81%94%E9%82%A6%E3%80%8B.md
新航季将至,部分城市机票预订热北京日报客户端记者潘福达3月26日,民航将迎来夏秋换季航班计划调整。去哪儿平台近日发布数据显示,2023年3月以来,国内多个城市机票预订量已恢复至疫情前水平。3月预订量前25名的城
如果陈婉婷做了女足主教练,带队成绩不好,球迷会喷她吗?群众的眼睛是雪亮的,输赢球的过程广大观众球迷是看的很清楚的!北京时间10月25日讯近日,女足选帅在中国足球圈闹得沸沸扬扬,多达6人同时竞聘这个位置也是出乎了不少球迷的意料,谁能承担
易建联是不是再也进不了国家队了?男篮是不是冲不出亚洲了?易建联只是现在不行,今年国家队比赛频繁,打世界杯正赛可能性很大,因要拿奥运参赛权易建联没有进国家队,事实上上半年也没有留下来,他现在身体状况怎么样,杜锋自然最清楚,他现在跟腱还是不
中国乒乓球史上谁最强?如果单从夺得世界冠军次数来说,男队第一人当属马龙,马龙截至目前总共获得102个冠军,在杜塞尔多夫世乒赛男单卫冕后,拿到第19个世界冠军,也超越了王皓和马琳,成为世界冠军数最多的运动
李铁是谁,做了什么,被人民日报和新华社批评?打铁的被人新批铁子是想不到的,他的格局显然到不了国家层面。他的着眼点也就在国足一个点上,这也就是他一而在在而三的胡调乱整的结证。想过球迷吗?想过一个央央大国在足球上苦苦突围寻求变革
广告侵入家电,消费者权益怎么保障?简单的聊一下我的观点目前大多数家庭都是购买国内几大品牌的电视或者网络智能电视,但是,凡是所谓的能联网的电视(智能电视),都会被不同时间的广告植入,哪怕你网速不好,广告的植入却都是优
漳州高新区关于做好2023年清明节祭扫服务工作的通告近日东山人的朋友圈短视频平台被蓝眼泪刷屏了3月22日晚10时许到3月23日凌晨,东山岛马銮湾帆船基地前面的沙滩惊现蓝眼泪,随着潮水渐渐涨起,越来越多的蓝眼泪被海浪冲上沙滩,蓝眼泪在
第十四届江苏省乡村旅游节即将启动,精彩内容先睹为快!千里莺啼绿映红,水村山郭酒旗风,在万物复苏的仲春时节,3月24日,省文旅厅举行第十四届江苏省乡村旅游节新闻发布会,宣布将于3月31日在泰州兴化市启动本届乡村旅游节。本届活动有那些精
又现低价团狂飙导游?赌团不可取近日,网友发布视频爆出三亚再现导游狂飙,导游称白白伺候几天,师傅一天就100元,要帮师傅卖特产。该视频显示,因游客未购物,导游称不听就下车。上个月,消费不达标不给房卡的事情热度还未
赏会船游湿地品八鲜!泰州姜堰溱潼会船节4月8日启幕新民晚报讯(记者唐闻宜通讯员黄苏乔梁丁明玥)天下会船数溱潼,溱潼会船甲天下!第十六届中国湿地生态旅游节暨2023中国泰州姜堰溱潼会船节将于4月8日在姜堰溱湖开幕。今天下午,2023
从旅游天堂到谈泰色变,泰国到底经历了什么?记得在今年的1月初,泰国副总理以及两位部长等政府官员一同亲自到机场为疫情放开后的首批中国游客接机的事情在全网传得很火。一瞬间,无数有钱有闲的国内游客被刺激了,纷纷计划上了去泰国的旅