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