微前端学习笔记(4):从微前端到微模块之EMP与hel-micro办法探索
<h2 style="color: black; text-align: left; margin-bottom: 10px;">ModuleFederation是啥?</h2>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">Module Federation<span style="color: black;">便是</span>一个JavaScript远程模块加载架构,即:Module federation allows a JavaScript application to <span style="color: black;"><strong style="color: blue;">dynamically run code from another bundle/build</strong></span><strong style="color: blue;">,</strong> on both client and server。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">它<span style="color: black;">准许</span>将一个应用程序的某些模块打包为一个独立的、可远程加载的 bundle,并在运行时动态地加载这些模块。<span style="color: black;">这般</span>,在另一个应用程序中就<span style="color: black;">能够</span><span style="color: black;">经过</span>远程容器加载这些模块,并直接<span style="color: black;">运用</span>它们。这种方式<span style="color: black;">能够</span>避免重复打包和加载相同的模块或库,<span style="color: black;">加强</span>了应用程序的性能和效率。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">复习一下核心概念:</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><strong style="color: blue;">module</strong>
</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">:每一个源码js文件其实都<span style="color: black;">能够</span>看成一个module</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><strong style="color: blue;">chunk</strong>:每一个打包落地的js文件其实都是一个chunk,<span style="color: black;">每一个</span>chunk都<span style="color: black;">包括</span><span style="color: black;">非常多</span>module</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><strong style="color: blue;">本地模</strong>块即为普通模块,是当前构建的一部分;</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><strong style="color: blue;">远程模块</strong>不属于当前构建,并在运行时从<span style="color: black;">所说</span>的容器加载。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">意见</span>读一下:《探索webpack5新特性Module federation在腾讯文档的应用》、《一文通透讲解webpack5 module federation》、《一文看透 Module Federation 下》</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><img src="https://mmbiz.qpic.cn/sz_mmbiz_png/tpDxj2yzpXK16280sV6he6njBcBBrPBzaeF0CS3dV4ddK57qTibiceaGmASXCIjpQybspC15mT7XnTUYfCo0X5Yg/640?wx_fmt=png&from=appmsg&tp=webp&wxfrom=5&wx_lazy=1&wx_co=1" style="width: 50%; margin-bottom: 20px;"></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">mf<span style="color: black;">供给</span>的能力<span style="color: black;">便是</span>把<strong style="color: blue;"><span style="color: black;"><span style="color: black;">每一个</span>应用中<span style="color: black;">能够</span>共用的component或library提取出来</span></strong><span style="color: black;">,<span style="color: black;">安排</span>到应用集群中,<strong style="color: blue;"><span style="color: black;">每一个</span>应用<span style="color: black;">能够</span>引用其他应用暴露出来的模块</strong>,<span style="color: black;">自己</span><span style="color: black;">亦</span>能被其他应用引用,这就实现了一个去中心化的应用<span style="color: black;">安排</span>集群</span>。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><img src="https://mmbiz.qpic.cn/sz_mmbiz_png/tpDxj2yzpXK16280sV6he6njBcBBrPBzY0g5YACibFATtZyhGvicuhTDNXztoOiaNBMYpic27YkTfed9cYgDzNtoYw/640?wx_fmt=png&from=appmsg&tp=webp&wxfrom=5&wx_lazy=1&wx_co=1" style="width: 50%; margin-bottom: 20px;"></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">在 webpack 的构建中,<span style="color: black;">每一个</span>构建结果其实都是隔离的,<span style="color: black;">那样</span>它是<span style="color: black;">怎样</span>打破这个隔离,实现应用间共享依赖呢?</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">关键在于 sharedScope,共享<span style="color: black;">功效</span>域,<strong style="color: blue;">在 Host 和 Remote 应用之间<span style="color: black;">创立</span>一个可共享的 sharedScope</strong>,它<span style="color: black;">包括</span>了所有可共享的依赖,<span style="color: black;">大众</span>都按<span style="color: black;">必定</span>规则往 sharedScope 里获取对应的依赖。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><img src="https://mmbiz.qpic.cn/sz_mmbiz_jpg/tpDxj2yzpXK16280sV6he6njBcBBrPBzLOhOQEhibbL2fBnia1cCibKRuGQtQOY6oXZt8fodMTGKfyNsv8ZwnNFlg/640?wx_fmt=other&from=appmsg&tp=webp&wxfrom=5&wx_lazy=1&wx_co=1" style="width: 50%; margin-bottom: 20px;"></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><strong style="color: blue;">Module Federation 基于 webpack 的<span style="color: black;">远程容器特性</span></strong>
</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">,详见:https://www.webpackjs.com/concepts/module-federation/#dynamic-remote-containers</p>
<h2 style="color: black; text-align: left; margin-bottom: 10px;">ModuleFederation<span style="color: black;">为么</span>而生?</h2>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">webpack和npm几乎形<span style="color: black;">成为了</span>完美搭档的状态,但前端<span style="color: black;">本来</span>从cdn获取的资源改由打包工具合并到一个包体里带来了致命的更新和<span style="color: black;">安排</span>效率问题。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">在某些需要需要动态更新的场景,这种all in one的打包机制让包体的<span style="color: black;">安排</span>效率大打折扣,这本不是webpack和npm的问题,而是人们天生对web环境需要快速迭代、快递实验的高<span style="color: black;">需求</span>带来的典型场景<span style="color: black;">需要</span>。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">注:externals 本身<span style="color: black;">不可</span>彻底<span style="color: black;">处理</span>动态更新的诉求,只适合于将底层公关依赖包体外链到cdn</span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">同期</span>webpack随着项目体积日趋庞大,新的问题诸如<span style="color: black;">研发</span>体验差(热更新慢)、包体加大、构建速度慢(node_modules黑洞)等问题<span style="color: black;">亦</span>诞生了,此时新生代的<span style="color: black;">研发</span>工具snow和vite以不打包的名义<span style="color: black;">起始</span>蚕食webpack的市场。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><img src="https://mmbiz.qpic.cn/sz_mmbiz_jpg/tpDxj2yzpXK16280sV6he6njBcBBrPBzTNwLnUHzRNdH6S8NeEv2fuWZwQj7mCHHnRibGD58Dr2icMibASLzGDTzQ/640?wx_fmt=other&from=appmsg&tp=webp&wxfrom=5&wx_lazy=1&wx_co=1" style="width: 50%; margin-bottom: 20px;"></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">她们</span>都利用了浏览器的原生模块化能力esm,跳过webpack的需要的依赖分析和打包流程,<span style="color: black;">这里</span>设计下做到了毫秒级的调试<span style="color: black;">起步</span>。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><img src="https://mmbiz.qpic.cn/sz_mmbiz_jpg/tpDxj2yzpXK16280sV6he6njBcBBrPBzUrib0sGt221DnGouTagicDJCN215ibR4km0wwpSDVw5FcJeTBXYMnrXXw/640?wx_fmt=other&from=appmsg&tp=webp&wxfrom=5&wx_lazy=1&wx_co=1" style="width: 50%; margin-bottom: 20px;"></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><strong style="color: blue;">模块联邦<span style="color: black;">因此呢</span>诞生了,它的伟大之处在于<span style="color: black;">保持当前前端<span style="color: black;">研发</span>模块化、组件化、工程化的<span style="color: black;">有效</span>率体系下,<span style="color: black;">准许</span>模块独立<span style="color: black;">研发</span>、独立<span style="color: black;">安排</span></span>,<span style="color: black;">经过</span> CDN 直接共享,从而挣脱npm包体<span style="color: black;">没法</span>动态更新的桎梏,从而推动<span style="color: black;">全部</span>前端界<span style="color: black;">研发</span>和运行体验<span style="color: black;">提升</span>到一个新高度</strong>。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">只要有越多的模块能<span style="color: black;">提高</span>到联邦里,本地<span style="color: black;">起步</span>速度将越快!</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">远程模块<span style="color: black;">能够</span><span style="color: black;">做为</span>微模块(模块级别的微前端),是页面级别的微前端的一种<span style="color: black;">弥补</span>,<span style="color: black;">由于</span>页面级别的微前端,如 qiankun、无界等,它们的粒度太粗了,有时候需要更细粒度的微前端,例如:组件、函数级别的。这种场景,就<span style="color: black;">能够</span><span style="color: black;">运用</span>远程模块,来实现微模块的效果。</p>
<h3 style="color: black; text-align: left; margin-bottom: 10px;">容器型微前端</h3>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">咱们</span>把<strong style="color: blue;">以single-spa为<span style="color: black;">表率</span>的这一类<span style="color: black;">方法</span>统<span style="color: black;">叫作</span>为微容器</strong>,在single-spa走红之后市面<span style="color: black;">非常多</span>基于single-spa二次封装的库如雨后春笋般涌出,典型的<span style="color: black;">表率</span>作如阿里的qiankun,意在<span style="color: black;">处理</span><span style="color: black;">有些</span>single-spa未<span style="color: black;">处理</span>的问题并让其更适合企业级<span style="color: black;">研发</span>,<span style="color: black;">同期</span><span style="color: black;">亦</span>诞生了<span style="color: black;">非常多</span>非singlespa系的框架,如京东的micro-app、腾讯的wujie等,它们的细节实现各有差异,<span style="color: black;">包括</span>js沙箱隔离、css隔离、iframe编排、启用web-component、window代理、接入过程等各个<span style="color: black;">地区</span>的细节<span style="color: black;">亦</span>各有千秋,但它们都一个<span style="color: black;">很<span style="color: black;">明显</span>的特点,对应的模块粒度是<span style="color: black;">全部</span>应用,做出的<span style="color: black;">制品</span><span style="color: black;">能够</span>理解为一种以宏观态的方式来组合多个应用交付给用户<span style="color: black;">运用</span></span>
</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">试想一下,你不会极端到以运行时隔离的方式去渲染多个按钮吧?</p>
<h3 style="color: black; text-align: left; margin-bottom: 10px;">模块型微前端</h3>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">相较于微容器宏观态的组合应用方式,<span style="color: black;"><strong style="color: blue;">微模块则<span style="color: black;">能够</span>形容为微观态的组合方式</strong></span><strong style="color: blue;">,它的粒度更小,小到<span style="color: black;">能够</span>是一个函数,一个<span style="color: black;">基本</span>的组件</strong>,<span style="color: black;">针对</span><span style="color: black;">研发</span>者<span style="color: black;">来讲</span>,引入微模块和引入一个普通的js包<span style="color: black;">无</span>任何区别,<span style="color: black;">她们</span>在<span style="color: black;">运用</span>上<span style="color: black;">亦</span>并无任何区别,但恰恰是这一点!是它和微容器最大差异之一,微模块的<span style="color: black;">运用</span>方式回归到了js语法本身。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><img src="https://mmbiz.qpic.cn/sz_mmbiz_jpg/tpDxj2yzpXK16280sV6he6njBcBBrPBzlYDu264RiaHvFfzDu4PwsWse4ZjbkEan2fUTYH8n95Jfy8cRABezgSw/640?wx_fmt=jpeg&from=appmsg&tp=webp&wxfrom=5&wx_lazy=1&wx_co=1" style="width: 50%; margin-bottom: 20px;"></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">这般</span>,微前端就变为:管好webpack生成的模块id,某种<span style="color: black;">道理</span>上<span style="color: black;">来讲</span>,hel经过统一的插件处理与加工并提取构建产物的元数据,相当于是对webpack的模块id做了统一管理,<span style="color: black;">然则</span><span style="color: black;">怎样</span>管理好并形成pass服务,这个从工程层面<span style="color: black;">怎样</span><span style="color: black;">处理</span>?</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">况且</span><span style="color: black;"><strong style="color: blue;">联邦模块天生<span style="color: black;">拥有</span>双重身份,即<span style="color: black;">能够</span>是模块消费者,<span style="color: black;">亦</span><span style="color: black;">能够</span>是模块<span style="color: black;">供给</span>者</strong></span>,这让模块联邦应用之间形<span style="color: black;">成为了</span>天然的网格关系,模块分发效率、<span style="color: black;">安排</span>效率、共享效率都得到了前所未有的<span style="color: black;">提高</span>!</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><img src="https://mmbiz.qpic.cn/sz_mmbiz_jpg/tpDxj2yzpXK16280sV6he6njBcBBrPBzZ6s5jhFVQyrmkWdiaLRhQ3uthlLsI4rTE7UxLRmEbC8lqVe1LicrlFFg/640?wx_fmt=other&from=appmsg&tp=webp&wxfrom=5&wx_lazy=1&wx_co=1" style="width: 50%; margin-bottom: 20px;"></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">远程模块<span style="color: black;">能够</span><span style="color: black;">做为</span>微模块(模块级别的微前端),是页面级别的微前端的一种<span style="color: black;">弥补</span>,<span style="color: black;">由于</span>页面级别的微前端,如 qiankun、无界等,它们的粒度太粗了,有时候需要更细粒度的微前端,例如:组件、函数级别的。这种场景,就<span style="color: black;">能够</span><span style="color: black;">运用</span>远程模块,来实现微模块的效果。</p><span style="color: black;">方法</span>微的定义微前端的定义技术实现<span style="color: black;">运用</span>场景MF模块由多个互相独立的模块聚合而成的应用模块本质上是JS代码片段,这种代码片段<span style="color: black;">通常</span><span style="color: black;">叫作</span>为chunk。<span style="color: black;">因此呢</span>,模块的聚合,<span style="color: black;">实质</span>上是chunk的聚合。是一种技术升级的创造性工作,有<span style="color: black;">必定</span>成本,目的是为了让系统具备更强大的能力。qiankun/wujie/garfish等应用由多个互相独立的应用聚合而成的应用应用本质上是HTML,而在SPA中,HTML又是main.js进行填充的。<span style="color: black;">因此呢</span>,应用的聚合,<span style="color: black;">实质</span>上是main.js的聚合。是一种维持<span style="color: black;">状况</span>的保守性工作,成本极小,目的是为了让系统<span style="color: black;">持有</span>更<span style="color: black;">很久</span>的生命力。模块联邦<span style="color: black;">优良</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">单体拆分的新<span style="color: black;">处理</span><span style="color: black;">方法</span>,更小的加载体积,当前子系统<span style="color: black;">已然</span>下载的chunk<span style="color: black;">能够</span>被共享,<span style="color: black;">倘若</span><span style="color: black;">能够</span>复用,下一个子系统将不会再次下载。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">降维打击了 systemjs, <span style="color: black;">况且</span><span style="color: black;">能够</span>在运行时拉远程模块和<span style="color: black;">2、</span>三方包,<span style="color: black;">因此</span>,systemjs 应该<span style="color: black;">能够</span>退场了。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">mf的远程模块是以webpack打包后的组件形式<span style="color: black;">供给</span>,<span style="color: black;">能够</span>按需在代码任意<span style="color: black;">地区</span>引用,像script标签的引用只适应在全局引用。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">运用</span>script的引用,只适应<span style="color: black;">全部</span>模块的共享,例如一个按钮组件,<span style="color: black;">运用</span>script的话就得单独为改组件分配一个共享域名,而<span style="color: black;">运用</span>mf<span style="color: black;">能够</span>在同一个域名内对一个应用的任意模块进行共享。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">相比过去, externals <span style="color: black;">没法</span>多版本共存,dll <span style="color: black;">没法</span>共享模块,MF 完美<span style="color: black;">处理</span>。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">处理</span>了从前用 NPM 公共包方式共享的<span style="color: black;">不方便</span>利。<span style="color: black;">不外</span>换来的是本地<span style="color: black;">起步</span>的巨量的 lib server 。</p>
<h3 style="color: black; text-align: left; margin-bottom: 10px;">模块联邦之痛</h3>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">webpack 5<span style="color: black;">或</span>其他工具带来的模块联邦实现真的完美了吗?</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">它的确<strong style="color: blue;"><span style="color: black;">处理</span>了免构建、动态更新、跨项目共享模块的问题</strong>,但基于现有的编译时插件化机制去实现,<strong style="color: blue;"><span style="color: black;"><span style="color: black;">没法</span>规避工具链强绑定,编译时确定<span style="color: black;">才可</span>远程模块消费关系的<span style="color: black;">困难</span></span></strong>!</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">MF虽然能做到依赖共享,<span style="color: black;">然则</span>被共享的lib<span style="color: black;">不可</span>做tree-shaken,<span style="color: black;">亦</span><span style="color: black;">便是</span>说<span style="color: black;">倘若</span>共享了一个lodash,<span style="color: black;">那样</span><span style="color: black;">全部</span>lodash库都会被打包到shared-chunk中。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">MF需升级到webpack5,就项目改<span style="color: black;">导致</span>本大,且webpack为了支持加载remote模块对runtime做了<span style="color: black;">海量</span>改造,在运行时要做的事情<span style="color: black;">亦</span><span style="color: black;">因此呢</span>陡然<span style="color: black;">增多</span>,可能会对<span style="color: black;">咱们</span>页面的运行时性能<span style="color: black;">导致</span><span style="color: black;">消极</span>影响。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">因此呢</span><span style="color: black;">倘若</span>要<span style="color: black;">运用</span>mf,就必须对当前的构建工具进行升级,并把现有应用可共享的模块进行提炼,工作量比<span style="color: black;">很强</span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">运行时共享<span style="color: black;">亦</span>是一把双刃剑,<span style="color: black;">怎样</span>去做版本<span style="color: black;">掌控</span>以及<span style="color: black;">掌控</span>共享模块的影响是需要去<span style="color: black;">思虑</span>的问题</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">针对<span style="color: black;">运用</span>react、vue这一类<span style="color: black;">研发</span>框架的应用,<span style="color: black;">运用</span>mf进行模块共享时还需<span style="color: black;">思虑</span>框架的版本,<span style="color: black;">倘若</span>是应用<span style="color: black;">处在</span><span style="color: black;">区别</span>的大版本,<span style="color: black;">那样</span>就有可能<span style="color: black;">引起</span>运行上下文的版本不一致,这<span style="color: black;">亦</span>是将应用接入微前端的难点之一。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><img src="https://mmbiz.qpic.cn/sz_mmbiz_png/tpDxj2yzpXK16280sV6he6njBcBBrPBz0XWQw1CL99fhA0ia2Cumc7mAXKq4lWWAbSRgAcVYem2l1lksStx7Xlg/640?wx_fmt=png&from=appmsg&tp=webp&wxfrom=5&wx_lazy=1&wx_co=1" style="width: 50%; margin-bottom: 20px;"></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">你需要<span style="color: black;">运用</span>模块联邦这么技术,需要做的前置<span style="color: black;">要求</span>有多重,需要升级<span style="color: black;">全部</span>工具链!<span style="color: black;">况且</span><span style="color: black;">区别</span>工具链之前的联邦模块是互相不通的!模块的流通性绑定在了你<span style="color: black;">选取</span>的工具链上。</p>
<h2 style="color: black; text-align: left; margin-bottom: 10px;">EMP</h2>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">https://github.com/empjs/emp</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">EMP <span style="color: black;">经过</span> module federation 实现依赖共享,使得依赖不会重新重复(依赖变成全局变量,相同依赖只会留下一个),<span style="color: black;">因此</span>体积会相对 qiankun 更小。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><img src="https://mmbiz.qpic.cn/sz_mmbiz_jpg/tpDxj2yzpXK16280sV6he6njBcBBrPBzQq9CzlJBKrCxmqYUKDxkULtp8cVWeqQlfrdmC6k07GpM5jKUXF43Yg/640?wx_fmt=other&from=appmsg&tp=webp&wxfrom=5&wx_lazy=1&wx_co=1" style="width: 50%; margin-bottom: 20px;"></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><strong style="color: blue;">跨框架调用实现</strong>。qiankun <span style="color: black;">经过</span> dom 隔离的方式,使得跨框架实现<span style="color: black;">非常</span>容易,<span style="color: black;">然则</span><span style="color: black;">不可</span>互相调用,粒度只能渲染在规定的 dom 区域。EMP 实现的跨框架调用粒度到了 function ,<span style="color: black;">况且</span><span style="color: black;">运用</span><span style="color: black;">非常</span>方便。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><strong style="color: blue;">体积方面</strong>。qiankun <span style="color: black;">由于</span>是<span style="color: black;">经过</span> dom 隔离方式实现,<span style="color: black;">因此</span>依赖共享并不完善,需要依赖于 systemjs,<span style="color: black;">况且</span>共享不方便,<span style="color: black;">引起</span>依赖可能会<span style="color: black;">显现</span>重复,使得<span style="color: black;">显现</span>体积变大。EMP <span style="color: black;">经过</span> module federation 实现依赖共享,使得依赖不会重新重复(依赖变成全局变量,相同依赖只会留下一个),<span style="color: black;">因此</span>体积会相对 qiankun 更小。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><img src="https://mmbiz.qpic.cn/sz_mmbiz_jpg/tpDxj2yzpXK16280sV6he6njBcBBrPBzYf1HgKtuRGiaXo3m3ziawpwgbVibdyoJkeBQ5zfOXUgeDpY4ejItx3mvA/640?wx_fmt=other&from=appmsg&tp=webp&wxfrom=5&wx_lazy=1&wx_co=1" style="width: 50%; margin-bottom: 20px;"></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">然则</span>EMP的<span style="color: black;">详细</span><span style="color: black;">背面</span>原理,暂时<span style="color: black;">无</span>时间去看源码</p>
<h2 style="color: black; text-align: left; margin-bottom: 10px;">hel-micro </h2>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">hel-micro 自<span style="color: black;">叫作</span>是:业内首个以sdk的方式支持模块联邦技术的<span style="color: black;">方法</span>,它脱离了工具链的枷锁,回归到js语言本身,接入快速、简单、灵活,<span style="color: black;">极重</span>的降低了模块联邦技术的接入门槛,让<span style="color: black;">区别</span>工具链间的联邦模块<span style="color: black;">能够</span>互认互通,<span style="color: black;">加强</span>了模块的流通性.</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">sdk化后,任何技术栈、任何工具链均可无损、无痛接入模块联邦技术。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><img src="https://mmbiz.qpic.cn/sz_mmbiz_jpg/tpDxj2yzpXK16280sV6he6njBcBBrPBz8PxVwnlhEzm9tsGpj6bmwcRAG8bpRzUPwYvOpOEtTAa0DgtbLJO6eg/640?wx_fmt=other&from=appmsg&tp=webp&wxfrom=5&wx_lazy=1&wx_co=1" style="width: 50%; margin-bottom: 20px;"></p>
<h3 style="color: black; text-align: left; margin-bottom: 10px;">运行时的模块消费关系</h3>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">从工具链回归到js语言本身,<span style="color: black;">寓意</span>着模块消费关系从编译时<span style="color: black;">提高</span>到运行时,将<span style="color: black;">极重</span><span style="color: black;">加强</span>动态载入远程模块的灵活性,为更<span style="color: black;">繁杂</span>的业务赋能。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><img src="https://mmbiz.qpic.cn/sz_mmbiz_jpg/tpDxj2yzpXK16280sV6he6njBcBBrPBzXUAjNWovkia1zU0OQSnqyibhFsMHI4z6PL0HgwIMxPIo3LNWoFqICs5g/640?wx_fmt=other&from=appmsg&tp=webp&wxfrom=5&wx_lazy=1&wx_co=1" style="width: 50%; margin-bottom: 20px;"></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">对比依赖工具插件实现的模块联邦,hel-micro从语言层面的实现将对其他模块联邦实现<span style="color: black;">导致</span>降维打击。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><img src="https://mmbiz.qpic.cn/sz_mmbiz_jpg/tpDxj2yzpXK16280sV6he6njBcBBrPBz1YgmWUwqXZxW8JPriaq44sVfmgTsRdrLfRvS4QKjFuXl7sgTGja5jqA/640?wx_fmt=other&from=appmsg&tp=webp&wxfrom=5&wx_lazy=1&wx_co=1" style="width: 50%; margin-bottom: 20px;"></p>
<h3 style="color: black; text-align: left; margin-bottom: 10px;">hel-micro <span style="color: black;">优良</span>如下:</h3>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">基于 sdk 的远程加载能力,<span style="color: black;">咱们</span><span style="color: black;">能够</span>搭配公共cdn<span style="color: black;">安排</span>远程模块(sdk默认指向unp<span style="color: black;">公斤</span>),用户<span style="color: black;">亦</span><span style="color: black;">能够</span><span style="color: black;">容易</span>定制自己的模块管控平台,<span style="color: black;">而后</span>重置sdk的请求模块元数据接口<span style="color: black;">就可</span>。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">基于核心层<span style="color: black;">供给</span>的远程加载能力,<span style="color: black;">咱们</span>规划了<span style="color: black;">更加多</span>的上层框架远程加载适配器,例如 远程web component组件,远程angular组件、远程vue组件、远程react组件(已实现为hel-micro-react,<span style="color: black;">供给</span>钩子函数加载远程react组件)等。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><img src="https://mmbiz.qpic.cn/sz_mmbiz_jpg/tpDxj2yzpXK16280sV6he6njBcBBrPBzxM8Z6CiaXxeDZuR5lfuBDNA815cnH1HvmPBibkveDib4oPJDThNC6XXRg/640?wx_fmt=other&from=appmsg&tp=webp&wxfrom=5&wx_lazy=1&wx_co=1" style="width: 50%; margin-bottom: 20px;"></p>
<h3 style="color: black; text-align: left; margin-bottom: 10px;">hel-micro实现原理</h3>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">一般</span><span style="color: black;">咱们</span>都会在头文件<span style="color: black;">运用</span>import关键字静态导入其他模块,但其实import<span style="color: black;">能够</span><span style="color: black;">做为</span>函数调用,异步的导入一个模块,并返回一个promise对象</p> <span style="color: black;">const</span> mod = <span style="color: black;">await</span> <span style="color: black;">import</span>(<span style="color: black;">./some-mod</span>);<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">因此</span><span style="color: black;">咱们</span><span style="color: black;">能够</span><span style="color: black;">经过</span>微调模块的加载<span style="color: black;">次序</span>,来达到为一个模块被其他模块静态导入之前能够为它注入新代码的效果</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><img src="https://mmbiz.qpic.cn/sz_mmbiz_jpg/tpDxj2yzpXK16280sV6he6njBcBBrPBz4UgbsnJ4vlvgT3s2mjmrSzujz7pibmhXFqx1jlNLBoWqBxeOmmgqvgw/640?wx_fmt=other&from=appmsg&tp=webp&wxfrom=5&wx_lazy=1&wx_co=1" style="width: 50%; margin-bottom: 20px;"></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">而这个异步import带来的提前注入效果<span style="color: black;">作为</span>了hel-micro为模块代理对象注入远程运行时代码的关键实现点,让hel-micro<span style="color: black;">能够</span>位用户<span style="color: black;">供给</span>懒加载和预加载两种加载方式。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><img src="https://mmbiz.qpic.cn/sz_mmbiz_jpg/tpDxj2yzpXK16280sV6he6njBcBBrPBzQoKurdU5L2ND9gs7ic6NEnjedW1QxaH5y96ho7Y3e6gkoYiaK5mEFx8w/640?wx_fmt=other&from=appmsg&tp=webp&wxfrom=5&wx_lazy=1&wx_co=1" style="width: 50%; margin-bottom: 20px;"></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">上图里两个核心接口:<strong style="color: blue;">libReady接口负责暴露模块,preFetchLib接口负责拉取模块</strong>,<span style="color: black;">经过</span>调用接口的<span style="color: black;">行径</span>让每一个模块都表现为<span style="color: black;">供给</span>方<span style="color: black;">或</span>消费者。运行时依赖分析</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><img src="https://mmbiz.qpic.cn/sz_mmbiz_jpg/tpDxj2yzpXK16280sV6he6njBcBBrPBzuV0iaibpQ5GSwrgXnPqiavbiaqw1a7tY5BicoUVrDx1FbP9TxBa4afJvnWg/640?wx_fmt=jpeg&from=appmsg&tp=webp&wxfrom=5&wx_lazy=1&wx_co=1" style="width: 50%; margin-bottom: 20px;"></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">当调用 helMicro.preFetchLib 时,先拉取元数据,从元数据中获取到入口脚本的 url,<span style="color: black;">而后</span>拉取远程模块入口并执行,最后 helMicro.preFetchLib 将模块返回,代码中就<span style="color: black;">能够</span>直接<span style="color: black;">运用</span>了。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">import 代理模块,<span style="color: black;">实质</span>上是从远程模块的缓存中读取模块。<span style="color: black;">因此呢</span>,必须要等待helMicro.preFetchLib拉取完成后,import 的代理模块<span style="color: black;">才可</span>够获取到远程模块</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">hel 的默认拉取元数据的方式,是<span style="color: black;">按照</span>远程模块名<span style="color: black;">叫作</span>,到 unp<span style="color: black;">公斤</span> CDN 对应的 npm 包下,获取元数据 meta_data.json 文件。这个拉取元数据的过程<span style="color: black;">亦</span><span style="color: black;">能够</span><span style="color: black;">研发</span>者自定义。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">hel-micro<span style="color: black;">经过</span>内部<span style="color: black;">守护</span>的事件总线、模块池、样式池、元数据池四个数据结构,让有多级依赖层次的远程模块得以<span style="color: black;">有效</span>并安全有序的加载。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><img src="data:image/svg+xml,%3C%3Fxml version=1.0 encoding=UTF-8%3F%3E%3Csvg width=1px height=1px viewBox=0 0 1 1 version=1.1 xmlns=http://www.w3.org/2000/svg xmlns:xlink=http://www.w3.org/1999/xlink%3E%3Ctitle%3E%3C/title%3E%3Cg stroke=none stroke-width=1 fill=none fill-rule=evenodd fill-opacity=0%3E%3Cg transform=translate(-249.000000, -126.000000) fill=%23FFFFFF%3E%3Crect x=249 y=126 width=1 height=1%3E%3C/rect%3E%3C/g%3E%3C/g%3E%3C/svg%3E" style="width: 50%; margin-bottom: 20px;"></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">其中模块池能<span style="color: black;">保准</span>模块不被重复加载并被上层各方调用者重复<span style="color: black;">运用</span>。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><img src="data:image/svg+xml,%3C%3Fxml version=1.0 encoding=UTF-8%3F%3E%3Csvg width=1px height=1px viewBox=0 0 1 1 version=1.1 xmlns=http://www.w3.org/2000/svg xmlns:xlink=http://www.w3.org/1999/xlink%3E%3Ctitle%3E%3C/title%3E%3Cg stroke=none stroke-width=1 fill=none fill-rule=evenodd fill-opacity=0%3E%3Cg transform=translate(-249.000000, -126.000000) fill=%23FFFFFF%3E%3Crect x=249 y=126 width=1 height=1%3E%3C/rect%3E%3C/g%3E%3C/g%3E%3C/svg%3E" style="width: 50%; margin-bottom: 20px;"></p>元数据-模块的灵魂<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">模块的实质是构建产物文件的集合,hel-micro<span style="color: black;">经过</span><span style="color: black;">供给</span>构建时的插件,收集好产物的网络路径并按sdk规定的协议存储起来,得以后续<span style="color: black;">能够</span>在网络让sdk<span style="color: black;">能够</span>下载并执行所有的远程模块。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><img src="data:image/svg+xml,%3C%3Fxml version=1.0 encoding=UTF-8%3F%3E%3Csvg width=1px height=1px viewBox=0 0 1 1 version=1.1 xmlns=http://www.w3.org/2000/svg xmlns:xlink=http://www.w3.org/1999/xlink%3E%3Ctitle%3E%3C/title%3E%3Cg stroke=none stroke-width=1 fill=none fill-rule=evenodd fill-opacity=0%3E%3Cg transform=translate(-249.000000, -126.000000) fill=%23FFFFFF%3E%3Crect x=249 y=126 width=1 height=1%3E%3C/rect%3E%3C/g%3E%3C/g%3E%3C/svg%3E" style="width: 50%; margin-bottom: 20px;"></p>双构建机制<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">hel-micro<strong style="color: blue;"><span style="color: black;">运用</span>rollup打包本地可静态导入的代理文件,<span style="color: black;">运用</span>webpack打包远程注入的<span style="color: black;">实质</span>运行代码</strong>,来达成<span style="color: black;">能够</span>本地静态导入node_modules里的代理模块对象得到完整的类型提示,让用户能得到像<span style="color: black;">运用</span>本地模块<span style="color: black;">同样</span>地<span style="color: black;">运用</span>远程模块的极致<span style="color: black;">研发</span>体验</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><img src="data:image/svg+xml,%3C%3Fxml version=1.0 encoding=UTF-8%3F%3E%3Csvg width=1px height=1px viewBox=0 0 1 1 version=1.1 xmlns=http://www.w3.org/2000/svg xmlns:xlink=http://www.w3.org/1999/xlink%3E%3Ctitle%3E%3C/title%3E%3Cg stroke=none stroke-width=1 fill=none fill-rule=evenodd fill-opacity=0%3E%3Cg transform=translate(-249.000000, -126.000000) fill=%23FFFFFF%3E%3Crect x=249 y=126 width=1 height=1%3E%3C/rect%3E%3C/g%3E%3C/g%3E%3C/svg%3E" style="width: 50%; margin-bottom: 20px;"></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><strong style="color: blue;">远程模块发布 CDN,在浏览器运行时</strong>,调用helMicro.preFetchLib真正拉取代码</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><strong style="color: blue;">代理模块用于<span style="color: black;">研发</span>时的类型提示</strong>,上传到 npm。<span style="color: black;">研发</span>时安装并<span style="color: black;">运用</span>该 npm 包,<span style="color: black;">能够</span><span style="color: black;">得到</span> TS 类型提示</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><strong style="color: blue;">元数据是一份 json 配置<span style="color: black;">名单</span></strong>,是在远程模块构建完成后,从构架产物中提取生成的。它记录了远程模块的名<span style="color: black;">叫作</span>、入口脚本路径等信息</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><img src="data:image/svg+xml,%3C%3Fxml version=1.0 encoding=UTF-8%3F%3E%3Csvg width=1px height=1px viewBox=0 0 1 1 version=1.1 xmlns=http://www.w3.org/2000/svg xmlns:xlink=http://www.w3.org/1999/xlink%3E%3Ctitle%3E%3C/title%3E%3Cg stroke=none stroke-width=1 fill=none fill-rule=evenodd fill-opacity=0%3E%3Cg transform=translate(-249.000000, -126.000000) fill=%23FFFFFF%3E%3Crect x=249 y=126 width=1 height=1%3E%3C/rect%3E%3C/g%3E%3C/g%3E%3C/svg%3E" style="width: 50%; margin-bottom: 20px;"></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">内定了4个目录hel_dist,hel_proxy,hel_proxy_es,hel_bundle来承载<span style="color: black;">区别</span>的产物,供package.json配置<span style="color: black;">区别</span>的入口。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><img src="data:image/svg+xml,%3C%3Fxml version=1.0 encoding=UTF-8%3F%3E%3Csvg width=1px height=1px viewBox=0 0 1 1 version=1.1 xmlns=http://www.w3.org/2000/svg xmlns:xlink=http://www.w3.org/1999/xlink%3E%3Ctitle%3E%3C/title%3E%3Cg stroke=none stroke-width=1 fill=none fill-rule=evenodd fill-opacity=0%3E%3Cg transform=translate(-249.000000, -126.000000) fill=%23FFFFFF%3E%3Crect x=249 y=126 width=1 height=1%3E%3C/rect%3E%3C/g%3E%3C/g%3E%3C/svg%3E" style="width: 50%; margin-bottom: 20px;"></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">其中hel_proxy,hel_proxy_es目录下的文件是<span style="color: black;">便是</span><span style="color: black;">咱们</span>说到的模块代理对象的入口文件,<span style="color: black;">咱们</span><span style="color: black;">能够</span>看到该文件近乎一个空壳,<span style="color: black;">因此</span>它对模块<span style="color: black;">运用</span>方的打包体积<span style="color: black;">体积</span>影响几乎<span style="color: black;">能够</span>省略不计。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><img src="data:image/svg+xml,%3C%3Fxml version=1.0 encoding=UTF-8%3F%3E%3Csvg width=1px height=1px viewBox=0 0 1 1 version=1.1 xmlns=http://www.w3.org/2000/svg xmlns:xlink=http://www.w3.org/1999/xlink%3E%3Ctitle%3E%3C/title%3E%3Cg stroke=none stroke-width=1 fill=none fill-rule=evenodd fill-opacity=0%3E%3Cg transform=translate(-249.000000, -126.000000) fill=%23FFFFFF%3E%3Crect x=249 y=126 width=1 height=1%3E%3C/rect%3E%3C/g%3E%3C/g%3E%3C/svg%3E" style="width: 50%; margin-bottom: 20px;"></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">参考<span style="color: black;">文案</span>:</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">hel-micro 模块联邦新革命 https://juejin.cn/post/7138792768234586148</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">腾讯开源的 hel <span style="color: black;">供给</span>了加载远程模块的能力,谈谈它的实现原理 https://zhuanlan.zhihu.com/p/591621582</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">关于module Federation的思考 https://geocld.github.io/2021/09/15/module-federation/</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">转载本站<span style="color: black;">文案</span>《微前端学习笔记(4):从微前端到微模块之EMP与hel-micro<span style="color: black;">方法</span>探索》,</p>请注明出处:https://www.zhoulujun.cn/html/webfront/engineer/Architecture/9063.html
你的见解真是独到,让我受益良多。
页:
[1]