共计 1651 个字符,预计需要花费 5 分钟才能阅读完成。
前言
关于 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 博客 ,转载必须注明作者及出处!