0

刨析webpack模块加载及模块联邦

 1 year ago
source link: https://www.haorooms.com/post/webpack_module_modulefile
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

关于webpack模块联邦,之前有文章提及过,详细请看Webpack5 新特性模块联邦介绍和应用,关于webpack模块联邦,我们已经在项目中用过很多,本文主要讲讲webpack模块加载,及模块联邦的一些原理性的东西,希望对您有所帮助。

webpack模块加载

首先,我们看下webpack是如何加载一个模块的,通过解析webpack打包之后的代码,我们发现,webpack对CommonJS规范和ES6 module规范 ,解析模块加载差不多,仅仅在导出的时候有所区别,因为es6经常是export default方式导出。我们看源码如下:

enter image description here

但是按需加载-import() 和 require.ensure 就不一样了

代码加载大概如下:

enter image description here

script方式加载如下:

enter image description here

我们可以看到,核心原理是通过创建script,远程拉取模块的方式。整个流程大概如下:

一、定义了一个对象 installedChunks,作用是缓存动态模块。

二、定义了一个辅助函数 jsonpScriptSrc(),作用是根据模块 ID 生成 URL

三、定义了两个新的核心函数 webpack_require.e() 和 webpackJsonpCallback()。

四、定义了一个全局变量 window["webpackJsonp"] = [],它的作用是存储需要动态导入的模块。

五、重写 window["webpackJsonp"] 数组的 push() 方法为 webpackJsonpCallback()。也就是说 window["webpackJsonp"].push() 其实执行的是 webpackJsonpCallback()。

Webpack-Module Federation 模块联邦

讲完了webpack模块加载,我们再来看看模块联邦,看官网对其介绍

enter image description here

其实chunk加载模块联邦是沿用了webpack按需加载的方式,只不过在其上面做了一些改进。

模块联邦源码截图如下:

enter image description here

ContainerPlugin的核心是实现容器的模块的加载与导出,从而在模块外侧进行一层的包装为了对模块进行传递与依赖分析

ContainerReferencePlugin核心是为了实现模块的通信与传递,通过调用反馈的机制实现模块间的传递

sharing的整个模块都在实现共享的功能,其利用Provider进行提供,Consumer进行消费的机制,将共享的数据隔离在特定的shareScope中

webpack5的模块联邦是在通过自定义Container容器来实现对每个不同module的处理, Container Reference作为host去调度容器,各个容器以异步方式exposed modules;

对于共享部分,对于provider提供的请求内容,每个module都有一个对应的runtime机制,其在分析完模块之间的调用关系及依赖关系之后,才会调用consumer中的运行时进行加载,而且shared的代码无需自己手动打包。

我们对比了webpack模块联邦-构建后代码的代码,发现相比上文介绍的webpack_require.e ,额外多做了如下事情:

enter image description here
enter image description here

overridables 可覆盖的,看代码和 shared 配置有关

remotes 远程的,看代码和 remotes 配置相关

jsonp 这个就是原有的加载 chunk 函数,对应的是以前的懒加载或者公共代码提取

动态远程容器

webpack 模块联邦,动态加载远程模块,远程容器接口支持 get 和 init 方法。 init 是一个兼容 async 的方法,调用时,只含有一个参数:共享作用域对象(shared scope object)。此对象在远程容器中用作共享作用域,并由 host 提供的模块填充。 可以利用它在运行时动态地将远程容器连接到 host 容器。

enter image description here
enter image description here

通过loadComponent方法就可以加载远程模块了。

通过理解了模块联邦的原理,我们可以基于模块联邦思路,做一些远程加载模块的事情,这里就是抛砖引玉,希望大家打开脑洞,希望本文对您有所帮助,本文haorooms博客,转载必须注明作者及出处!


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK