模块联合(Module federation)允许 JavaScript 应用在客户端和服务器上动态运行来自另一个包或版本的代码。
油管视频:https://youtu.be/D3XYAx30CNc
我们需要一个可扩展的解决方案来共享 node 模块和功能与应用程序代码。它需要在运行时发生,以便具有适应性和动态性。 Externals
并不能有效或灵活地完成工作;Import maps 无法解决规模问题。我并不是要单独下载代码并共享依赖项,而是需要一个业务编配层,该层能够在运行时动态地共享模块,并有后备功能。
什么是模块联合(Module Federation)?
Module Federation
是我发明并原型化的一种 JavaScript 体系结构。然后,在我的联合创始人和 Webpack 创始人的帮助下— —它变成了 Webpack 5 核心中最令人兴奋的功能之一(里面有一些很棒的东西,新的 API 确实功能强大且简洁)。
模块联合(Module Federation) 允许 JavaScript 应用动态地从另一个应用中加载代码,然后在过程中共享依赖项。如果使用模块联合的应用程序不具有联合代码所需的依赖项,则 Webpack 将从该联合的生成源中下载缺少的依赖项
术语
- Module federation(模块联合):与 Apollo GraphQL 联合有着相同的思想——但适用于 JavaScript 模块,可用在浏览器和 node.js 中——通用模块联合
- host(主机):一种 Webpack 构建,该构建在页面加载期间首先初始化(触发 onLoad 事件时)
- remote(远程主机):另一个 Webpack 构建,其中一部分被 “host” 所用
- Bidirectional-hosts(双向主机):当 bundle 或 Webpack 构建时可以作为主机或作为远程主机使用。可在运行时使用其他应用程序或着被其他人使用
更多介绍: https://github.com/webpack/webpack/issues/10352
怎样构建联合应用程序
太多了不爱写,详情参考
代码重复
几乎没有依赖项重复。通过 shared 选项 —— 远程将依赖于主机依赖关系,如果主机没有依赖关系,则 remote 将下载自己的依赖关系。没有代码重复,但是内置冗余。
手动将供应商或其他模块添加到 shared
并不理想。可以用自定义编写的函数或补充性的 Webpack 插件轻松地将其自动化。我们确实打算发布 AutomaticModuleFederationPlugin
并从 Webpack
核心外部对其进行维护。既然我们已经在 Webpack 中内置了一流的代码联合支持,那么扩展其功能就变得微不足道了。
服务器端渲染
我们将其设计为通用的。模块联合可在任何环境中使用。在服务器端渲染联合代码是完全可能的。只需让服务器构建使用 commonjs 库目标即可。有多种实现联合 SSR 的方法:S3流、ESI、自动执行 npm 发布以使用服务器变体。我计划用公共共享文件卷或异步 S3 流在整个文件系统中流式传输文件,使服务器能够像在浏览器中一样请求联合代码,并用 fs
而不是 http
来加载联合代码。
module.exports = {
plugins: [
new ModuleFederationPlugin({
name: "container",
library: { type: "commonjs-module" },
filename: "container.js",
remotes: {
containerB: "../1-container-full/container.js"
},
shared: ["react"]
})
]
};
“模块联合也可以与
target:"node"
一起使用。作为代替指向其他微前端的 URL,在这里用指向其他微前端的文件路径。这样你可以使用相同的代码库和不同的 webpack 配置进行 SSR,以构建 node.js。对于 node.js 中的 Module Federation,相同的属性仍然适用:e.g. 单独构建,单独部署” —— Tobias Koppers