当前位置: 首页 > news >正文

吐槽一次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 }, // 禁用缓存
 );

效果如下

有缓存的时候

开启缓存之后

没有缓存

禁用缓存之后

写在最后

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

相关文章:

  • 【从零开始实现stm32无刷电机FOC】【实践】【7.1/7 硬件设计】
  • Nginx部署前端Vue项目的深度解析
  • 【计算机网络最全知识点问答】第二章 物理层
  • 828华为云征文|部署在线论坛网站 Flarum
  • 为了学习Python熬夜部署了Jupyter Notebook 6.x
  • 使用 Nexus 代理 Docker Hub 的配置指南
  • python爬虫初体验(三)——将网页数据导出csv和excel文件
  • Python快速上手爬虫的7大技巧
  • 回归预测 | Matlab基于SO-ESN蛇群算法优化回声状态网络多输入单输出回归预测
  • Python字符串基础和处理
  • CSS 效果:实现动态展示双箭头
  • fish-speech语音大模型本地部署
  • Leetcode 3306. Count of Substrings Containing Every Vowel and K Consonants II
  • 针对考研的C语言学习(定制化快速掌握重点2)
  • Zabbix 7.0 图表中文乱码问题处理步骤
  • u2net网络模型训练自己数据集
  • 【Linux】包管理器、vim详解及简单配置
  • 9月27日,每日信息差
  • MATLAB案例 | 沪深股市收益率的二元Copula模型
  • sql中的regexp与like区别
  • 婚姻登记“全国通办”首日,上海虹口登记中心迎来“甜蜜高峰”
  • 国家主席习近平会见斯洛伐克总理菲佐
  • 习近平会见塞尔维亚总统武契奇
  • 涨知识|没想到吧,体育老师强调的运动恢复方法是错的?
  • 青年与人工智能共未来,上海创新创业青年50人论坛徐汇分论坛举办
  • “一嗨租车”陷“五年后扣费”疑云,用户:违章处理莫名消失