概念
Webpack 模块联邦是一种先进的代码共享技术,它允许在多个独立构建的 Web 应用程序之间共享代码,而无需将这些代码提前发布到 npm 仓库或其他中央存储。
这项技术特别适用于微前端架构,因为它能让各个前端团队独立开发、部署自己的应用,同时还能无缝共享组件、库或功能模块。
通俗点说就是在微前端架构中每个应用都是独立的,独立开发,独立部署,在开发过程中避免不了有些模块是重复使用的,如何把这些重复的模块利用起来,一般情况下会通过 npm 进行安装或者相关代码重复编写,这样做不好的地方就是代码冗余,因为是微前端,会出现很多重复的内容,重复进行编写,开发效率降低,而模块联邦就很好的解决了这些问题。
好处
动态加载:模块可以在运行时动态加载,仅在需要时加载相关功能模块,减少初始加载体积,加速页面加载。
代码重用:可以共享通用的库和组件,避免重复代码,优化代码复用率。
版本管理:各个模块可以独立升级和版本化,不会因某个模块的更新影响整个应用。
性能优化:共享库避免重复包含,打包体积更小,网络传输更快,提高应用性能。
关键概念
主容器与远程容器
- 主容器(Host):负责加载其他应用模块的应用,消费模块的容器。
- 远程容器(Remote):提供模块供其他应用加载的应用,提供模块的容器。
动态加载
模块联邦允许应用在运行时动态加载其他应用的模块,而不是在构建时静态合并。这使得各个应用可以独立构建和部署,运行时按需加载所需的模块。
举例说明一下
假设场景
我们有两个独立的项目:app1
和 app2
。
app1
想要复用 app2
中的一个名为 CoolButton
的组件。
创建主容器应用(Host)
首先,安装 Webpack 5 和相关插件:
npm install webpack webpack-cli html-webpack-plugin --save-dev
设置 app2
作为共享模块的提供者(远程容器)
首先,在 app2
的 webpack.config.js
文件中,我们需要配置 app2
以共享 CoolButton
组件。
// app2/webpack.config.js
module.exports = {
output: {
publicPath: 'http://localhost:3002/', // 公共路径,确保在不同域下也能正确加载
uniqueName: 'app2', // 确保在联邦中的唯一命名
},
plugins: [
new webpack.container.ModuleFederationPlugin({
name: 'app2',
filename: 'remoteEntry.js',
exposes: {
'./CoolButton': './src/components/CoolButton', // 共享 CoolButton 组件
},
}),
],
};
在 app1
中消费 app2
提供的 CoolButton
组件(主容器)
接下来,在 app1
中,我们需要配置 app1
以消费来自 app2
的 CoolButton
。
// app1/webpack.config.js
module.exports = {
plugins: [
new webpack.container.ModuleFederationPlugin({
name: 'app1',
remotes: {
app2: 'app2@http://localhost:3002/remoteEntry.js', // 指定app2的远程入口
},
shared: {
react: { singleton: true },
'react-dom': { singleton: true },
},
}),
],
};
然后,在 app1
的代码中,我们可以像导入本地模块一样导入 app2
的 CoolButton
:
// app1/src/index.js
import React from 'react';
import ReactDOM from 'react-dom';
import CoolButton from 'app2/CoolButton';
ReactDOM.render(
<React.StrictMode>
<div>
<h1>Welcome to App1</h1>
<CoolButton label="Click me!" />
</div>
</React.StrictMode>,
document.getElementById('root')
);
总结
以上对模块联邦进行简单的介绍,当然实际使用当中还要根据各自的项目进行配置,大家可以查看官方文档进行更深一步了解Webpack 5 发布 (2020-10-10) | webpack 中文文档