在大型应用中, 我们可能会对其进行拆分,分成容器、主应用和多个子应用,使拆分后的应用独立开发与部署,更加容易维护。但无论是微应用、公共模块应用,都需要放到容器中才能使用。
如果多个应用之间希望资源共享,除了使用 npm 包的形式,基于Webpack 5 Module Federation(模块联邦)实现的EMP微前端方案也可以一试,它不限制技术栈,但依赖于 Webpack5。
使用场景
如果应用B需要使用应用A中的User模块,那么应用B就相当于容器,同时应用A也可以使用来自应用C的Menu模块,此时应用A变成了容器。
如何使用
要想使用 Module Federation,肯定是需要搭建 webpack 环境,配置方式也比较简单,使用 ModuleFederationPlugin 分别导出/导出即可。
A应用导出文件
webpack配置需要导出的文件路径和名称
// 其余配置省略
const Mfp = require('webpack').container.ModuleFederationPlugin;
module.exports = {
plugins: [
new Mfp({
// 对外提供打包后的文件名
filename: 'user.js',
// 导出的应用/组织什么名字
name: 'userComponent',
// 要导出哪一个文件,key值为引入时的名字,value为当前文件路径
exposes: {
'./username': './src/username.js',
'./userHobby': './src/userHobby.js',
}
})
]
}
B应用导入文件
webpack设置需要导入的资源地址和名称
const Mfp = require('webpack').container.ModuleFederationPlugin
plugins: [
new Mfp({
name: 'root',
// key值为导入后使用的名字,value为导出的 filename@文件地址/name,设置本地服务地址方便调试
remotes: {
userComponent: 'userComponent@http://localhost:3001/user.js'
}
})
]
在需要使用的js文件中异步导入,userComponent 是定义的导入后的名字,斜杠(/)加上导出文件webpack配置exposes属性的文件名
const Username = React.lazy(()=>import('userComponent/username'))
const UserHobby = React.lazy(()=>import('userComponent/userHobby'))
return (
<React.Suspense fallback="loading">
<Username/>
<UserHobby/>
</React.Suspense>)
引入后,http://localhost:3001/user.js
将会被加载,并且资源内容挂载到 window 对象中。
这样,便可以达到应用之间共享组件的目的。
以上就是 Webpack Module Federation(模块联邦)
的介绍, 更多有关 前端
、工程化
的内容可以参考我其它的博文,持续更新中~
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。