前言
关于webpack模块联邦,之前有文章提及过,详细请看Webpack5 新特性模块联邦介绍和应用,关于webpack模块联邦,我们已经在项目中用过很多,本文主要讲讲webpack模块加载,及模块联邦的一些原理性的东西,希望对您有所帮助。
webpack模块加载
首先,我们看下webpack是如何加载一个模块的,通过解析webpack打包之后的代码,我们发现,webpack对CommonJS规范和ES6 module规范 ,解析模块加载差不多,仅仅在导出的时候有所区别,因为es6经常是export default方式导出。我们看源码如下:
但是按需加载-import() 和 require.ensure 就不一样了,
代码加载大概如下:
script方式加载如下:
我们可以看到,核心原理是通过创建script,远程拉取模块的方式。整个流程大概如下:
一、定义了一个对象 installedChunks,作用是缓存动态模块。
二、定义了一个辅助函数 jsonpScriptSrc(),作用是根据模块 ID 生成 URL
三、定义了两个新的核心函数 webpack_require.e() 和 webpackJsonpCallback()。
四、定义了一个全局变量 window["webpackJsonp"] = [],它的作用是存储需要动态导入的模块。
五、重写 window["webpackJsonp"] 数组的 push() 方法为 webpackJsonpCallback()。也就是说 window["webpackJsonp"].push() 其实执行的是 webpackJsonpCallback()。
Webpack-Module Federation 模块联邦
讲完了webpack模块加载,我们再来看看模块联邦,看官网对其介绍
其实chunk加载模块联邦是沿用了webpack按需加载的方式,只不过在其上面做了一些改进。
模块联邦源码截图如下:
ContainerPlugin的核心是实现容器的模块的加载与导出,从而在模块外侧进行一层的包装为了对模块进行传递与依赖分析
ContainerReferencePlugin核心是为了实现模块的通信与传递,通过调用反馈的机制实现模块间的传递
sharing的整个模块都在实现共享的功能,其利用Provider进行提供,Consumer进行消费的机制,将共享的数据隔离在特定的shareScope中
webpack5的模块联邦是在通过自定义Container容器来实现对每个不同module的处理, Container Reference作为host去调度容器,各个容器以异步方式exposed modules;
对于共享部分,对于provider提供的请求内容,每个module都有一个对应的runtime机制,其在分析完模块之间的调用关系及依赖关系之后,才会调用consumer中的运行时进行加载,而且shared的代码无需自己手动打包。
我们对比了webpack模块联邦-构建后代码的代码,发现相比上文介绍的webpack_require.e ,额外多做了如下事情:
overridables 可覆盖的,看代码和 shared 配置有关
remotes 远程的,看代码和 remotes 配置相关
jsonp 这个就是原有的加载 chunk 函数,对应的是以前的懒加载或者公共代码提取
动态远程容器
webpack 模块联邦,动态加载远程模块,远程容器接口支持 get 和 init 方法。 init 是一个兼容 async 的方法,调用时,只含有一个参数:共享作用域对象(shared scope object)。此对象在远程容器中用作共享作用域,并由 host 提供的模块填充。 可以利用它在运行时动态地将远程容器连接到 host 容器。
通过loadComponent方法就可以加载远程模块了。
小结
通过理解了模块联邦的原理,我们可以基于模块联邦思路,做一些远程加载模块的事情,这里就是抛砖引玉,希望大家打开脑洞,希望本文对您有所帮助,本文haorooms博客,转载必须注明作者及出处!