qiankun
qiankun copied to clipboard
webpack5 使用模块联邦,抛出异常,生命周期未加载
webpack5 使用模块联邦,抛出异常,生命周期未加载
在webpack5 使用模块联邦时(子应用作为consume),要求webpack的entry要被额外包装一层,处理成动态引入,如果按照要求使用,那么这时候主应用不能检测到子应用的生命周期,如果只把生命周期也放在这一层,内部不加任何逻辑,是没问题的,但是生命周期中需要做渲染,那么就需要引入react,就会出现异常。请问有什么处理方案吗

碰到一样的问题,mark
碰到一样的问题,mark
没找到方案,避开了,放弃了模块联邦
碰到一样的问题,mark
没找到方案,避开了,放弃了模块联邦
解决了。
1、把入口改成:
const { bootstrap, mount, unmount, update } = await import('./main')
export { bootstrap, mount, unmount, update }
webpack要设置一下 experiments: { topLevelAwait: true }
2、webpack配置的output.library不能跟ModuleFederationPlugin里的name一样。调试了一下发现如果一样的话在import-html-entry里边获取qiankun生命周期会失败
碰到一样的问题,mark
没找到方案,避开了,放弃了模块联邦
解决了。
1、把入口改成:
const { bootstrap, mount, unmount, update } = await import('./main') export { bootstrap, mount, unmount, update }webpack要设置一下
experiments: { topLevelAwait: true }2、webpack配置的output.library不能跟ModuleFederationPlugin里的name一样。调试了一下发现如果一样的话在import-html-entry里边获取qiankun生命周期会失败
问下这个是哪里看到的方案吗?还是怎么考虑到的?
碰到一样的问题,mark
没找到方案,避开了,放弃了模块联邦
解决了。 1、把入口改成:
const { bootstrap, mount, unmount, update } = await import('./main') export { bootstrap, mount, unmount, update }webpack要设置一下
experiments: { topLevelAwait: true }2、webpack配置的output.library不能跟ModuleFederationPlugin里的name一样。调试了一下发现如果一样的话在import-html-entry里边获取qiankun生命周期会失败问下这个是哪里看到的方案吗?还是怎么考虑到的?
自己调试找的办法。你可以试试你项目里能不能用
碰到一样的问题,mark
没找到方案,避开了,放弃了模块联邦
解决了。 1、把入口改成:
const { bootstrap, mount, unmount, update } = await import('./main') export { bootstrap, mount, unmount, update }webpack要设置一下
experiments: { topLevelAwait: true }2、webpack配置的output.library不能跟ModuleFederationPlugin里的name一样。调试了一下发现如果一样的话在import-html-entry里边获取qiankun生命周期会失败问下这个是哪里看到的方案吗?还是怎么考虑到的?
自己调试找的办法。你可以试试你项目里能不能用
请教下,模块联邦在qiankun中引入的用途是什么呢
碰到一样的问题,mark
没找到方案,避开了,放弃了模块联邦
解决了。 1、把入口改成:
const { bootstrap, mount, unmount, update } = await import('./main') export { bootstrap, mount, unmount, update }webpack要设置一下
experiments: { topLevelAwait: true }2、webpack配置的output.library不能跟ModuleFederationPlugin里的name一样。调试了一下发现如果一样的话在import-html-entry里边获取qiankun生命周期会失败问下这个是哪里看到的方案吗?还是怎么考虑到的?
自己调试找的办法。你可以试试你项目里能不能用
请教下,模块联邦在qiankun中引入的用途是什么呢
项目中一个特殊模块用到了模块联邦,webpack升级到了5,后来想把项目拆分成微前端。组内有其他项目用了qiankun,所以用的一样的。
碰到一样的问题,mark
没找到方案,避开了,放弃了模块联邦
解决了。 1、把入口改成:
const { bootstrap, mount, unmount, update } = await import('./main') export { bootstrap, mount, unmount, update }webpack要设置一下
experiments: { topLevelAwait: true }2、webpack配置的output.library不能跟ModuleFederationPlugin里的name一样。调试了一下发现如果一样的话在import-html-entry里边获取qiankun生命周期会失败问下这个是哪里看到的方案吗?还是怎么考虑到的?
自己调试找的办法。你可以试试你项目里能不能用
请教下,模块联邦在qiankun中引入的用途是什么呢
我们项目的情况是拆分了很多qiankun微模块,各个微模块之间重复代码需要复用,用npm的话更新一次要更新十几个微模块,想用联合模块来复用这些代码
碰到一样的问题,mark
没找到方案,避开了,放弃了模块联邦
解决了。 1、把入口改成:
const { bootstrap, mount, unmount, update } = await import('./main') export { bootstrap, mount, unmount, update }webpack要设置一下
experiments: { topLevelAwait: true }2、webpack配置的output.library不能跟ModuleFederationPlugin里的name一样。调试了一下发现如果一样的话在import-html-entry里边获取qiankun生命周期会失败问下这个是哪里看到的方案吗?还是怎么考虑到的?
自己调试找的办法。你可以试试你项目里能不能用
请教下,模块联邦在qiankun中引入的用途是什么呢
项目中一个特殊模块用到了模块联邦,webpack升级到了5,后来想把项目拆分成微前端。组内有其他项目用了qiankun,所以用的一样的。
补充一下:
- 只是配置
experiments: { topLevelAwait: true }是不行的,如果用到babel的话,需要额外配置plugin(https://stackoverflow.com/questions/64815808/toplevelawait-invalid-with-babel-loader-await-is-only-allowed-within-async-fu)。 - 照这方法试了,还是不行,报错Uncaught Error: application 'app2' died in status LOADING_SOURCE_CODE: [qiankun]: You need to export lifecycle functions in app2 entry
既然使用了webpack5的模块联邦,那就不应该再使用qiankun了,模块联邦本身就可以实现微前端架构
碰到一样的问题,mark
没找到方案,避开了,放弃了模块联邦
解决了。 1、把入口改成:
const { bootstrap, mount, unmount, update } = await import('./main') export { bootstrap, mount, unmount, update }webpack要设置一下
experiments: { topLevelAwait: true }2、webpack配置的output.library不能跟ModuleFederationPlugin里的name一样。调试了一下发现如果一样的话在import-html-entry里边获取qiankun生命周期会失败问下这个是哪里看到的方案吗?还是怎么考虑到的?
自己调试找的办法。你可以试试你项目里能不能用
请教下,模块联邦在qiankun中引入的用途是什么呢
项目中一个特殊模块用到了模块联邦,webpack升级到了5,后来想把项目拆分成微前端。组内有其他项目用了qiankun,所以用的一样的。
补充一下:
- 只是配置
experiments: { topLevelAwait: true }是不行的,如果用到babel的话,需要额外配置plugin(https://stackoverflow.com/questions/64815808/toplevelawait-invalid-with-babel-loader-await-is-only-allowed-within-async-fu)。- 照这方法试了,还是不行,报错Uncaught Error: application 'app2' died in status LOADING_SOURCE_CODE: [qiankun]: You need to export lifecycle functions in app2 entry
不好意思我漏写了一步,要在html-webpack-plugin里面改一下chunksSortMode,把入口js放最后面,因为mf生成的remoteEntry.js默认是在最后的,
但是后面又发现了解决不了的问题 ,基座和微应用的页面共享同一个vue组件的时候,在这两个页面切换会报错,大致原因是基座和微应用都引入了一次vue,两次创建的vnode类型symbol(xxx)匹配不上。暂时放弃两者结合了,要么用qiankun要么用mf。不知道react会不会也有这个问题
既然使用了webpack5的模块联邦,那就不应该再使用qiankun了,模块联邦本身就可以实现微前端架构
确实,感觉两者的设计思路就是相反的两个方向
碰到一样的问题,mark
没找到方案,避开了,放弃了模块联邦
解决了。 1、把入口改成:
const { bootstrap, mount, unmount, update } = await import('./main') export { bootstrap, mount, unmount, update }webpack要设置一下
experiments: { topLevelAwait: true }2、webpack配置的output.library不能跟ModuleFederationPlugin里的name一样。调试了一下发现如果一样的话在import-html-entry里边获取qiankun生命周期会失败问下这个是哪里看到的方案吗?还是怎么考虑到的?
自己调试找的办法。你可以试试你项目里能不能用
请教下,模块联邦在qiankun中引入的用途是什么呢
项目中一个特殊模块用到了模块联邦,webpack升级到了5,后来想把项目拆分成微前端。组内有其他项目用了qiankun,所以用的一样的。
补充一下:
- 只是配置
experiments: { topLevelAwait: true }是不行的,如果用到babel的话,需要额外配置plugin(https://stackoverflow.com/questions/64815808/toplevelawait-invalid-with-babel-loader-await-is-only-allowed-within-async-fu)。- 照这方法试了,还是不行,报错Uncaught Error: application 'app2' died in status LOADING_SOURCE_CODE: [qiankun]: You need to export lifecycle functions in app2 entry
不好意思我漏写了一步,要在html-webpack-plugin里面改一下chunksSortMode,把入口js放最后面,因为mf生成的remoteEntry.js默认是在最后的,
但是后面又发现了解决不了的问题 ,基座和微应用的页面共享同一个vue组件的时候,在这两个页面切换会报错,大致原因是基座和微应用都引入了一次vue,两次创建的vnode类型symbol(xxx)匹配不上。暂时放弃两者结合了,要么用qiankun要么用mf。不知道react会不会也有这个问题
1.是的,需要在Hosts应用的webpack中加配置
chunks: ['app2','app'], // 让入口文件晚于remoteEntry加载
chunksSortMode: "manual"
2.我把Remotes应用入口文件也改成了异步导出,然后发现可以了,我的是React应用,现在在demo中能正常使用。
可以看一下我的demo代码: https://github.com/GeWeidong/federation-demos
我认为比较好的解决方案:写一个 webpack plugin 然后 hook 到 html-webpack-plugin 写入标签之前的时机,在回调函数中为我们的入口 script(可以通过正则匹配) 属性添加 ‘entry’ 即可。
mark
谢谢,呵呵!~~
@wudith
更好的去做代码共享,复用公共依赖。之前可能我们使用 external,cdn,等方式提取公共依赖,或者用单独 npm 包的方式抽取公共代码逻辑, 现在用模块联邦可以直接做到.
谢谢,呵呵!~~
"要求webpack的entry要被额外包装一层,处理成动态引入" 这个并不是MF必要的配置,而是webpack的建议:异步边界(asynchronous boundary) ,我目前没有使用这种在入口异步引用的方式,qiankun可以正常使用MF,代码中用到远程模块时,直接用 await import('remote/module1') 这种就行了
谢谢,呵呵!~~
我认为比较好的解决方案:写一个 webpack plugin 然后 hook 到 html-webpack-plugin 写入标签之前的时机,在回调函数中为我们的入口 script(可以通过正则匹配) 属性添加 ‘entry’ 即可。
尝试通过plugins设置入口 script,属性添加‘entry’后,依旧报错“找不到子应用生命周期” demo地址:https://github.com/w123angmeng/demo
谢谢,呵呵!~~
碰到一样的问题,mark
没找到方案,避开了,放弃了模块联邦
遇到同样问题,现在有解决方案吗,组件共享不用模块联邦,有什么好的替代方案吗?
碰到一样的问题,mark
没找到方案,避开了,放弃了模块联邦
解决了。 1、把入口改成:
const { bootstrap, mount, unmount, update } = await import('./main') export { bootstrap, mount, unmount, update }webpack要设置一下
experiments: { topLevelAwait: true }2、webpack配置的output.library不能跟ModuleFederationPlugin里的name一样。调试了一下发现如果一样的话在import-html-entry里边获取qiankun生命周期会失败问下这个是哪里看到的方案吗?还是怎么考虑到的?
自己调试找的办法。你可以试试你项目里能不能用
请教下,模块联邦在qiankun中引入的用途是什么呢
项目中一个特殊模块用到了模块联邦,webpack升级到了5,后来想把项目拆分成微前端。组内有其他项目用了qiankun,所以用的一样的。
补充一下:
- 只是配置
experiments: { topLevelAwait: true }是不行的,如果用到babel的话,需要额外配置plugin(https://stackoverflow.com/questions/64815808/toplevelawait-invalid-with-babel-loader-await-is-only-allowed-within-async-fu)。- 照这方法试了,还是不行,报错Uncaught Error: application 'app2' died in status LOADING_SOURCE_CODE: [qiankun]: You need to export lifecycle functions in app2 entry
不好意思我漏写了一步,要在html-webpack-plugin里面改一下chunksSortMode,把入口js放最后面,因为mf生成的remoteEntry.js默认是在最后的,
但是后面又发现了解决不了的问题 ,基座和微应用的页面共享同一个vue组件的时候,在这两个页面切换会报错,大致原因是基座和微应用都引入了一次vue,两次创建的vnode类型symbol(xxx)匹配不上。暂时放弃两者结合了,要么用qiankun要么用mf。不知道react会不会也有这个问题
1.是的,需要在Hosts应用的webpack中加配置
chunks: ['app2','app'], // 让入口文件晚于remoteEntry加载 chunksSortMode: "manual"2.我把Remotes应用入口文件也改成了异步导出,然后发现可以了,我的是React应用,现在在demo中能正常使用。
可以看一下我的demo代码: https://github.com/GeWeidong/federation-demos
项目是vue2.x demo地址:https://github.com/w123angmeng/demo.git 子仓库入口配置: const { bootstrap, mount, unmount } = await import('./bootstrap') export { bootstrap, mount, unmount } 还是报错找不到子应用生命周期函数
碰到一样的问题,mark
没找到方案,避开了,放弃了模块联邦
解决了。 1、把入口改成:
const { bootstrap, mount, unmount, update } = await import('./main') export { bootstrap, mount, unmount, update }webpack要设置一下
experiments: { topLevelAwait: true }2、webpack配置的output.library不能跟ModuleFederationPlugin里的name一样。调试了一下发现如果一样的话在import-html-entry里边获取qiankun生命周期会失败问下这个是哪里看到的方案吗?还是怎么考虑到的?
自己调试找的办法。你可以试试你项目里能不能用
请教下,模块联邦在qiankun中引入的用途是什么呢
项目中一个特殊模块用到了模块联邦,webpack升级到了5,后来想把项目拆分成微前端。组内有其他项目用了qiankun,所以用的一样的。
补充一下:
- 只是配置
experiments: { topLevelAwait: true }是不行的,如果用到babel的话,需要额外配置plugin(https://stackoverflow.com/questions/64815808/toplevelawait-invalid-with-babel-loader-await-is-only-allowed-within-async-fu)。- 照这方法试了,还是不行,报错Uncaught Error: application 'app2' died in status LOADING_SOURCE_CODE: [qiankun]: You need to export lifecycle functions in app2 entry
不好意思我漏写了一步,要在html-webpack-plugin里面改一下chunksSortMode,把入口js放最后面,因为mf生成的remoteEntry.js默认是在最后的,
但是后面又发现了解决不了的问题 ,基座和微应用的页面共享同一个vue组件的时候,在这两个页面切换会报错,大致原因是基座和微应用都引入了一次vue,两次创建的vnode类型symbol(xxx)匹配不上。暂时放弃两者结合了,要么用qiankun要么用mf。不知道react会不会也有这个问题
1.是的,需要在Hosts应用的webpack中加配置
chunks: ['app2','app'], // 让入口文件晚于remoteEntry加载 chunksSortMode: "manual"2.我把Remotes应用入口文件也改成了异步导出,然后发现可以了,我的是React应用,现在在demo中能正常使用。 可以看一下我的demo代码: https://github.com/GeWeidong/federation-demos
项目是vue2.x demo地址:https://github.com/w123angmeng/demo.git 子仓库入口配置: const { bootstrap, mount, unmount } = await import('./bootstrap') export { bootstrap, mount, unmount } 还是报错找不到子应用生命周期函数
我上面那个解法,react 是没有问题的,vue 我就不知道了。
各位大佬们,现在这个问题有好的解决办法了吗? @w123angmeng
谢谢,呵呵!~~
各位大佬们,现在这个问题有好的解决办法了吗? @w123angmeng
- 子仓库入口改成 import('./bootstrap') ;
- 公共组件项目 MF配置 share配置注释掉; 通过以上处理,qiankun + MF 能实现组件共享,但第三方依赖共享还是有问题(配置share报错);
各位大佬们,现在这个问题有好的解决办法了吗? @w123angmeng
- 子仓库入口改成 import('./bootstrap') ;
- 公共组件项目 MF配置 share配置注释掉; 通过以上处理,qiankun + MF 能实现组件共享,但第三方依赖共享还是有问题(配置share报错);
谢谢大佬
子应用配置 mf 以后,只需要把用到 remote 的逻辑放在异步边界里就行了,其余的逻辑可以不用改,也可以不用开 topLevelAwait。
import '../public-path'
async function bootstrapWithoutQiankun() {
if (!window.__POWERED_BY_QIANKUN__) {
const { render } = await import('./bootstrap')
render({})
}
}
bootstrapWithoutQiankun()
const umountHandlerRef: { current?: () => void } = { current: undefined }
export async function bootstrap() {
console.log('[react18] react app bootstrapped')
}
export async function mount(props: any) {
const { render, unmount } = await import('./bootstrap')
render({})
umountHandlerRef.current = unmount
}
export async function unmount() {
console.log('[react18] react app unmount')
umountHandlerRef.current?.()
}
我这边用 mf 共享了 react 组件,所以把 render 的逻辑放 bootstrap 就可以。