吐槽一次qiankun微前端的框架

背景

心血来潮,想在自己的个人网站中体验一下微前端的魅力,其实也是为了满足我自己多个应用便于统一查看,而不需要跳来跳去的打开n多标签页,
不过微前端出来的主要目的:还是为了解决,真正使用中,多个团队协作共同维护同一个项目的不同模块,而互不影响上线流程,以及前端由于一个应用中n多模块导致的臃肿问题

目的

解决掉我现在的问题,以及体验微前端的框架使用

选型

qiankun : 毕竟这几年沸沸扬扬的微前端理念使用,大多都是用它,它底层一直是基于single-spa而封装的适合业务形态使用的框架。
qiankun官网
npm i -S qiankun
个人觉得文档还是比较糙,在使用中,很多时候还是要看源码 痛苦面具

  • 主应用:react项目
  • 微应用:原生的js项目(本文的例子)、vue项目、react项目、agular项目

说明

什么是主应用? 它就是让别的应用嵌入进入的宿主

什么是微应用? 它就是嵌入到别人应用的寄生虫

可以理解,就是宿主和寄生虫的关系!

简单的使用

解决两个问题:

  1. 主应用(宿主)怎么加载微应用(寄生虫)?
  2. 微应用(寄生虫)满足什么条件可以在主应用加载?(什么样的寄生虫可以进入宿主)

问题1

两种方式:(看这里

  1. 批量加载微应用–适合作为一个路由,也就是一整个页面 registerMicroApps
  2. 单个加载微应用–适合作为单个组件,在某个页面的一部分 loadMicroApp

我是按照第二种方式使用的,如下

import React, { useRef, useEffect } from "react";
import { loadMicroApp, type MicroApp } from "qiankun";

const musicUrl = "xxx";
/**
 * @abstract https://qiankun.umijs.org/zh/api#loadmicroappapp-configuration
 */
function MicroAppComp() {
  const microAppRef = useRef<HTMLDivElement>(null);
  const microApp = useRef<MicroApp>();

  useEffect(() => {
    const init = () => {
      if (!microAppRef.current) return;
      microApp.current = loadMicroApp(
        {
          name: "music",
          entry: musicUrl,
          container: microAppRef.current,
        });
    };
    init();

    return () => {
      microApp.current?.unmount();
    };
  }, []);

  return <div ref={microAppRef} />;
}

export default MicroAppComp;

随便当作一个组件使用即可,跟其他react组件没区别的。

问题2

满足的条件,这里以原生的js项目为例

/** 
  * 这段代码后续会在qiankun加载的时候,源码中读取的
  * 
  */
((global) => {
    global['music'] = {
      bootstrap: () => {
        return Promise.resolve();
      },
      mount: () => {
        console.log('music mount');
        // render不需要写,页面所有的渲染都已用原声写完了,这里只是用来qiankun框架在运行loadApp 的时候,读取微应用的这个方法
      },
      unmount: () => {
        console.log('music unmount');
        return Promise.resolve();
      }
    };
  })(window);

以上就是按照qiankun的设计方案,我们使用的微应用要添加的生命周期的钩子函数,当然你不加入,也会给你友好的报错 信息类似于:You need to export lifecycle functions in XXX entry

吐槽点

按照以上配置之后,可以使用
在这里插入图片描述
但是,
不完美的点在于,当我切换左侧的tab,在此点回来之后,对应的音乐组件不会重新加载,就像是这样
在这里插入图片描述
我歌词数据呢,然后发现是再次进来不加载了(估计设置了缓存)

查看源码,果不其然,发现qiankun项目开发团队,设置了缓存memorizedLoadingFn;

当我想通过配置去掉缓存,可是源码中根本不支持配置,很难受,希望可以加上配置!

当然我知道设计者的初衷是为了让我们用mount这个钩子函数去触发渲染render逻辑,但是有些时候,就是有这种情况存在,可以搞个配置让使用者关闭缓存(当然开发者会去承担没缓存导致页面每次加载应用过慢的后果呀)

诉求

加个配置项,让用户可以自己启用或者禁用缓存 (默认禁用)

暴力解决

直接通过脚本,在npm i之后,将源码的某一个文件替换掉,主要是为了屏蔽设置缓存的那段代码
这里会有三种方式的引入目录dist、es、lib
在这里插入图片描述
run.sh

# 我使用的是esmodule模块,大家根据自己的实际情况哈 
# 比如你用外部引入 <link>标签 那就改dist中的index.umd.js代码了 require那就是lib目录下面要替换了
cp myown/apis.js node_modules/qiankun/es/apis.js 

package.json

 "scripts": {
	"start": "npm run pre:run && node scripts/start.js",
	"pre:run": "sh ./scripts/run.sh"
}

在这里插入图片描述
注释代码232-236行

  • 为了更好的兼容是否开启缓存,我们也可以这样,(最好是锁住你的qiankun依赖的版本)如下
    将注释的代码替换为这样的:
if (container) {
  if ($$cacheLifecycleByAppName) {
    appConfigPromiseGetterMap.set(
      name,
      parcelConfigObjectGetterPromise,
    );
  }
}

使用的时候,传入配置{ $$cacheLifecycleByAppName: false }:

loadMicroApp(
   {
     name: "music",
     entry: musicUrl,
     container: microAppRef.current,
   },
   { $$cacheLifecycleByAppName: false }, // 禁用缓存
 );

效果如下

有缓存的时候

开启缓存之后

没有缓存

禁用缓存之后

写在最后

如果博主这篇文章,有帮助到大家,记得给博主点个赞,多多支持!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不cong明的亚子

鼓励和支持,是我每滴汗水的见证

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值