介绍

什么是微前端

前端是一种架构风格,通过将一个单体应用程序拆分成多个小型独立应用程序实现每个小型应用程序都专注于一项特定功能,并且可以独立部署扩展和维护。

为什么需要前端

大型单体应用程序随着时间的推移变得越来越复杂,难以维护

前端允许团队根据其能力和需求独立工作,而不需要干扰其他团队

使用不同的技术堆栈开发各个独立应用程序,而无需考虑整体应用程序技术选型

核心价值

框架限制接入应用技术栈,子应用具备完全自主权

子应用仓库独立,前后端可独立开发部署完成后主框架自动完成同步更新

独立运行时每个子应用之间状态隔离,运行时状态共享

优点

通过添加新应用程序扩展系统而无需修改原始代码

每个应用程序可以独立部署、减少了系统的停机时间

由于应用程序之间相互独立,因此如果一个应用程序发生故障,其他应用程序可以继续运行

缺点

qiankun ——一套完整的微前端解决方案

qiankun能很方便的将一个巨石应用改造成一个基于微前端框架的系统,并且不再需要去关注各种过程中的技术细节,做到真正的开箱即用和生产可用

特点

任意js框架均可使用,微应用接入使用接入一个iframe统一简单,但实际不是iframe

  • 完备

几乎包含所有构建微前端系统时所需的基本能力,如样式隔离js沙箱、预加载

  • 生产可用

已在蚂蚁内外经受过足够大量的线上系统的考验及打磨,健壮性值得信赖

使用方法

主应用(vue3+vite+TypeScript
  1. 创建项目

    npm init vue@latest
    
  2. 安装qiankun

    yarn add qiankun
    
  3. main.ts注册微应用

    import { registerMicroApps, addGlobalUncaughtErrorHandler, start } from 'qiankun';
    // 注册子应用
    registerMicroApps([
      {
        // 子应用名称name值必须与子应用vite.config.ts文件plugins属性qiankun的第一个参数值一致
        name: 'subApp',
        // 默认加载这个路径下的html解析里面的js
        entry: '//localhost:5174',
        // 加载容器(微应用会显示到这个容器里面,一定要保证主应用中有这个容器)
        container: '#subAppContainerVue3',  // 和app.vue配置节点一致
        // 匹配路由
        activeRule: '/junminronghe', // 访问http://localhost:5174/juminronghe
        props: {
            mag: '我是主应用main', // 主应用向微应用传递参数
            domain: 'http://localhost:5174',
        },
      }
      // 再有其他子应用,同理
    ]);
    // 启动 qiankun
    start({
        prefetch:'all', // 预加载
        sandbox: {
            experimentalStyleIsolation: true, //   开启沙箱模式,实验性方案
        },
    });
    
    // 添加全局异常捕获
    addGlobalUncaughtErrorHandler((handler) => {
        console.log("异常捕获", handler);
    });
    
  4. app.vue创建挂载节点,如再有其他子应用,也是同理

    <div id="subAppContainerVue3"></div>
    
  5. 访问子应用

    <script setup lang="ts">
    import { useRouter } from 'vue-router'
    
    const router = useRouter();
    function goToFunc() {
      router.push('/junminronghe');
    }
    </script>
    
    <template>
      <main>
        <div @click="goToFunc">子应用</div>
      </main>
    </template>
    
子应用(vue3+vite+TypeScript)
  1. 安装vite-plugin-qiankunqiankun官方不支持vite)需要安装插件

    yarn add vite-plugin-qiankun
    
  2. vite.config.ts

    import { fileURLToPath, URL } from 'node:url'
    import vue from '@vitejs/plugin-vue'
    import qiankun from 'vite-plugin-qiankun'
    
    export default defineConfig({
      plugins: [
        vue(),
      	// qiankun的第一个参数必须与主应用在main.tsregisterMicroAppsname值一致
        qiankun('vue3', {
          useDevMode: true
        })
      ],
      server:{
        headers: {
          'Access-Control-Allow-Origin': '*', // 主应用获取子应用时跨域响应
        },
      },
      resolve: {
        alias: {
          '@': fileURLToPath(new URL('./src', import.meta.url))
        }
      }
    })
    
  3. main.ts

    import { createApp } from 'vue'
    import { renderWithQiankun, qiankunWindow, QiankunProps } from 'vite-plugin-qiankun/dist/helper'
    import App from './App.vue'
    import router from './router'
     
    const app = createApp(App)
     
    app.use(router)
     
    // app.mount('#app')
    // renderWithQiankun: 为子应用导出一些生命周期函数 供主应用在特殊的时机调用
    // qiankunWindow: qiankunWindow.POWERED_BY_QIANKUN 可判断是否在qiankun环境
    const initQianKun = () => {
        renderWithQiankun({
            // bootstrap 只会在微应用初始化的时候调用一次,下次微应用重新进入时会直接调用 mount 钩子,不会再重复触发 bootstrap
            // 通常我们可以这里做一些全局变量初始化比如不会在 unmount 阶段被销毁的应用级别缓存
            bootstrap() {
                console.log('bootstrap');
            },
            // 应用每次进入都会调用 mount 方法,通常我们这里触发应用的渲染方法,也可以接受主应用传来的参数
            mount(_props: any) {
                console.log('mount', _props);
                render(_props.container)
            },
            // 应用每次 切出/卸载 会调用的unmount方法,通常在这里我们卸载微应用的应用实例
            unmount(_props: any) {
                console.log('unmount', _props);
            },
            update: function (props: QiankunProps): void | Promise<void> {
                console.log('update');
            }
        });
    }
     
    const render = (container) => {
        // 如果是在主应用的环境下就挂载主应用的节点,否则挂载本地
        const appDom = container ? container : "#app"
        app.mount(appDom)
    }
    // 判断是否为乾坤环境,否则会报错[qiankun]: Target container with #subAppContainerVue3 not existed while subAppVue3 mounting!
    qiankunWindow.__POWERED_BY_QIANKUN__ ? initQianKun() : render(null)
    
  4. router——》index.ts

    import { createRouter, createWebHistory, RouteRecordRaw } from 'vue-router'
    import { qiankunWindow } from 'vite-plugin-qiankun/dist/helper'
    
    const routes: RouteRecordRaw[] = [
      {
        path: '/',
        name: 'home',
        component: () => import('../views/home/index.vue')
      },
      // 文章详情
      {
        path: '/content',
        name: 'content',
        component: () => import('../views/content/index.vue')
      },
    ];
    
    const router = createRouter({
      history: createWebHistory(
        // 在乾坤环境下时,将所有的路由地址前加上'/junminronghe',否则将跳转至主应用的相应页面(eg:跳转这里文章详情页面,如果不加'/junminronghe'的话,将跳转至主应用的'/content'页面,如果主应用没有这个页面,将跳转至404页面)
        qiankunWindow.__POWERED_BY_QIANKUN__ ? '/junminronghe' : '/'
      ),
      routes
    })
    export default router
    
    

1、子应用的本地资源图片等)显示404

解决方法

在子应用的vite.config.ts文件server对象配置origin属性配置为子应用的链接地址

server:{
  port: 5174,
  // origin用于定义开发调试阶段生成资产的 origin
  // 子应用的地址用于解决主应用中子应用出现静态地址404问题控制报错显示资源在主应用路劲下
  origin: 'http://localhost:5174',
}
2、子应用的接口404

在创建axios实例时,配置baseURL

子应用:

// 创建 axios 实例
const instance = axios.create({
  // API 请求默认前缀
  // "/junminrongheApi"要跟主应用,vite.config.ts中,代理地址一致,给所有的接口请求地址前加“/junminrongheApi"字符串,表明是junminronghe子应用的接口
  baseURL: qiankunWindow.__POWERED_BY_QIANKUN__ ? '/junminrongheApi' : '',
  timeout: 60 * 1000, //设置超时
  headers: {
    "Content-Type": "application/json;charset=UTF-8;",
    "Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8",
    ".AspNetCore.Culture": "c=zh-Hans|uic=zh-Hans",
  },
});

主应用:vite.config.ts

export default defineConfig({
  plugins: [vue()],
  server: {
    proxy: {
      // "/junminrongheApi"要跟子应用,service——》index.ts中,baseURL的地址一致(即axios的baseURL地址一致),
      // 将junminronghe子应用的接口地址代理到其自己的地址(即target与主应用main.ts中registerMicroApps的entry值,保持一致)即可
      "/junminrongheApi": {
        target: 'http://localhost:5174', // 后台接口
        changeOrigin: true,
        secure: false, // 如果是https接口,需要配置这个参数
        // ws: true, //websocket支持
        rewrite: (path) => path.replace(/^/junminrongheApi/, ""),
      },
    }
  },
  resolve: {
    alias: {
      '@': fileURLToPath(new URL('./src', import.meta.url))
    }
  }
})
3、子应用的线上图片地址显示404(一般不会有这个问题

注:这个是因为这里的图片地址不是常规的地址,而是像这样的地址:sysFileInfo/preview?id=1666025519278534658,所以才会出现这个问题,这个问题是特例,正常的图片地址(eg:https://vitejs.cn/vite3-cn/logo.svg)就不会有这个问题

解决方法

在所有的图片地址前,手动拼接一个请求地址,可以封装一个图片组件统一管理

eg:

<n-image :object-fit="props.objectFit" :src="previewUrl + props.url" />

文本中的图片,在加载时,图片地址(sysFileInfo/preview?id=1666025519278534658)前会被拼上主应用的地址及前面配置的子应用路由拼接'/junminronghe'(目前不知道是为啥)

解决方法

主应用vite.config.ts

export default defineConfig({
  plugins: [vue()],
  server: {
    proxy: {
      // "/junminrongheApi"要跟子应用,service——》index.ts中,baseURL的地址一致(即axios的baseURL地址一致),
      // 将junminronghe子应用的接口地址代理到其自己的地址(即target与主应用main.ts中registerMicroApps的entry值,保持一致)即可
      "/junminrongheApi": {
        target: 'http://localhost:5174', // 后台接口
        changeOrigin: true,
        secure: false, // 如果是https接口,需要配置这个参数
        // ws: true, //websocket支持
        rewrite: (path) => path.replace(/^/junminrongheApi/, ""),
      },
      // 加这个代理是因为像子应用中如果有富文本,并且富文本中有图片的话,请求的图片会在主应用的地址后面拼上子应用的路由地址(即这里的junminronghe)后再是图片的地址,
      // 当然是因为这里的子应用的图片地址不是常规的地址,而是像这样的地址:sysFileInfo/preview?id=1666025519278534658,才会有这样的问题
      "/junminronghe": {
        target: 'http://localhost:5174', // 后台接口
        changeOrigin: true,
        secure: false, // 如果是https接口,需要配置这个参数
        // ws: true, //websocket支持
        rewrite: (path) => path.replace(/^/junminronghe/, ""),
      },
    }
  },
  resolve: {
    alias: {
      '@': fileURLToPath(new URL('./src', import.meta.url))
    }
  }
})

原文地址:https://blog.csdn.net/m0_37653407/article/details/131109089

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。

如若转载,请注明出处:http://www.7code.cn/show_11917.html

如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱suwngjj01@126.com进行投诉反馈,一经查实,立即删除

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注