
本系列大纲
- 微前端模块联邦实践系列(1) - 微前端入门
- 微前端模块联邦实践系列(2) - 微前端与模块联邦
- 微前端模块联邦实践系列(3) - 第一个案例
- 微前端模块联邦实践系列(4) - subApp之间共享libraries
- 微前端模块联邦实践系列(5) - Path to Production
- 微前端模块联邦实践系列(6) - 集成React & Vue
- 微前端模块联邦实践系列(7) - 路由管理
- 微前端模块联邦实践系列(8) - 消息通信
在前面的例子中,我们采用了手撸的方式在页面中插入了3个节点。
在实际的开发中并不会像上述那么简单,我们会用到很多第三方库。如果每个项目中都引入了相同的三方库,势必会造成代码重复,加大了main的bundle体积,因此在某些情况下,我们需要将第三方库进行拆离,做成一个shared module来共享代码。
这篇文章主要来看看如何在subApp之间共享第三方库以及在引入相同模块的不同版本时是如何加载的?
我们本文中采用引入lodash为例。
配置shared模块 lodash
new ModuleFederationPlugin({
// ...
shared: ['lodash'],
})
使用相同的版本
- container:
lodash@4.17.21 - subApp:
lodash@4.17.21
打开localhost:8080,lodash模块只有一个版本,来源于posts。
使用lodash的不同major版本
- container:
lodash@3.10.1 - subApp:
lodash@4.17.21
打开localhost:8080,lodash模块会来源于两个subApp,分别是container以及posts。
使用lodash的不同minor(patch)版本
- container:
lodash@4.17.20 - subApp:
lodash@4.17.21
打开localhost:8080,lodash模块只有一个版本,来源于posts。
强制使用相同的版本
- container:
lodash@3.10.1 - subApp:
lodash@4.17.21
配置singleton: true,强制使用相同模块的最高版本。
new ModuleFederationPlugin({
// ...
shared: [
{
lodash: {
singleton: true,
requiredVersion: false,
},
},
],
})
打开localhost:8080,lodash模块只有一个版本,来源于posts。
结论
- 如果不同app中,使用相同模块的major版本不同,默认情况下会采用保留两个模块,分别加载
- 如果不同app中,使用相同或者不同minor/patch版本,默认情况下则会合并成一个vendor,取版本最高的加载
- 强制使用某个版本,在某些特殊情况下可能会出现问题,比如高版本不谦容低版本的某些api,在使用
singleton的时候应该特别注意
shared dependencies
我们可以直接共享package.json中的所有denpendecies,让webpack module federation给我们自动生成所有共享模块的vendor。
// apps/container/config/webpack.dev.js (posts/albums 配置类似)
const packageJson = require('../package.json')
new ModuleFederationPlugin({
// ...
shared: packageJson.dependencies,
})
Subapp (posts/albums) 单独加载出现了问题?
在子subApp配置了shared之后,打开localhost:8081出现了问题,是什么原因?
然后我们可以打开network面板,切换到js
发现应用本身在加载时,也load了remoteEntry.js,因此加载Shared module本身从同步变成了异步,所以我们要对subapp的加载采取和container类似的操作,新建bootstrap.js,将index.js的内容全部copy过去,然后在index.js中加载bootstrap
// apps/posts/src/index.js (albums类似)
import('./bootstrap')
修改exposes的导出文件
// apps/posts/config/webpack.dev.js
new ModuleFederationPlugin({
name: 'posts',
filename: 'remoteEntry.js',
exposes: {
'./PostsIndex': './src/bootstrap',
},
shared: packageJson.dependencies,
})
重启webpack之后,就ok了。