背景
前端工程从vue2升级到vue3之后,vue-cli脚手架版本升级至vue/cli-service@5.0.8,对应webpack版本为webpack@5.90.2。发现作为qiankun框架的子应用本地开发报错“You need to export the functional lifecycles”
搜索官网方案,简单排查了一下,由于vue-cli脚手架自带wepack配置,不单独处理入口entry文件,尝试了情况9,打印(typeof exports === 'object' && typeof module === 'object') || (typeof define === 'function' && define.amd) || typeof exports === 'object',值为false,不满足,便使用情况10进行本地开发,修改library与主应用配置的子应用entry名称一致,可解决该问题。
vue项目可正常启动开发,但由于所处的工程复杂,一套工程代码采用多个菜单来展示,也就是对于qiankun来说,我这一套工程实际上包含好几个子应用。如果按照情况10来处理,6个菜单我得部署6套流水线来适配不同子应用入口,每一套都得处理域名后缀重新部署,太麻烦了。
网上搜索方案,基本都指向官网的方案,官网总结的不全面的话还能有谁解决呢?便开始仔细查看每一种情况的含义。 每一种情况进行排除。
- 由于之前vue2时正常运行,
排除情况1,2,3,4。 - 情况5需要修改entry入口,搜了一下vue-cli自带入口,没有外设配置的位置,
排除5。
同时也get到入口文件entry的概念。
情况7,8使用webpack5符合当前情况,区别在于“模块联邦”,模块联邦(webpack5推出的一个新功能,叫module federation,中文叫模块联邦,它提供了一套在不同项目构建之间的调度、运行机制。复用模块只需要在一个项目中修改, 其他项目都能生效,可实现跨应用共享代码。)并未使用“模块联邦”概念,符合方案7
仔细查看方案7,说明原因是 webpack-dev-server版本问题,仅影响开发环境(但在我所处项目中,最终发现不仅仅出现在开发环境,发布之后仍会出现报错“You need to export the functional lifecycles”)
最终方案
首先,在原有入口文件main.ts下新增window.qiankunLifecycle声明
export async function bootstrap() {
console.log('bootstrap');
}
export async function mount(props) {
console.log('mount');
}
export async function unmount(props) {
console.log('unmount');
}
/**
* 可选生命周期钩子,仅使用 loadMicroApp 方式加载微应用时生效
*/
export async function update() {
console.log('update');
}
/**
* 解决办法:
* 1.先将 qiankun 需要的生命周期函数挂到 window(供别处使用)
* 2.在 index.html 底部注入 js,将生命周期函数挂到 window['purehtml'] 上
* 灵感来自:
* - https://github.com/umijs/qiankun/issues/1846
* - https://qiankun.umijs.org/zh/guide/tutorial#%E9%9D%9E-webpack-%E6%9E%84%E5%BB%BA%E7%9A%84%E5%BE%AE%E5%BA%94%E7%94%A8
*
* 本地和运行环境都需要去掉。
*/
+ window.qiankunLifecycle = {
+ bootstrap,
+ mount,
+ unmount,
+ update,
+ };
然后,在index.html下新增入口entry脚本
<html>
<head>
</head>
<body>
</body>
+ <script entry>
+ if (window.__POWERED_BY_QIANKUN__) {
+ window.purehtml = window.qiankunLifecycle;
+ }
+ </script>
</html>
至此,在开发环境和发布的环境均可正常运行工程。