qiankun框架 You need to export the functional lifecycles in

1,270 阅读2分钟

背景

前端工程从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>

至此,在开发环境和发布的环境均可正常运行工程。