微前端框架之qiankun 怎么用?vue3+vite+qiankun 和 react + qiankun

1、什么是微前端

微前端是一种前端架构模式 ,核心思想是------把后端微服务的理念搬到前端:将一个庞大的"巨石单体应用"拆成多个独立开发、独立构建、独立部署、运行时聚合 的小型前端应用(子应用/微应用),再由一个**主应用(基座/Shel)**负责统一加载和组合。

特点就是:微前端并不微,可以使用多个技术栈,独立开发部署

2、创建项目

1、main-app

使用vue3 作为基座,

pnpm create vue@latest

一步步往下走

2、app1

react 作为子应用

npx create-react-app app1

一步步往下走

3、app2

vue3+vuecil作为子应用

vue create app2

使用上面的命令一步步往下走

好了 一个主应用+两个子应用 创建完成

接下来配置main-app 主应用

主应用先装个qiankun框架

pnpm add qiankun

先建个index.js

javascript 复制代码
export default {
  microApp: [
    {
      name: 'app1',
      entry: '//127.0.0.1:8002',
      activeRule: '/app-react',
      container: '#container',
      props: { parent: 'base' },
    },
    {
      name: 'app2',
      entry: '//127.0.0.1:8003',
      activeRule: '/app-vue',
      container: '#container',
      props: {},
    },
  ],
}

#container 是需要显示的容器id

/app-vue 是地址栏的路由路径

接下来编写app.vue

javascript 复制代码
<script setup>
import { RouterLink, RouterView } from 'vue-router'
import { registerMicroApps, start, addGlobalUncaughtErrorHandler } from "qiankun";
import config from "./index";
const { microApp } = config;

// 初始化乾坤
const initQiankun = () => {
  if (microApp.length) {
    registerMicroApps(microApp, {
      beforeLoad(app) {
        console.log("app=>", app);
      },
      beforeMount: [() => console.log('before mount')],
      afterMount: () => console.log('****afterMount*****'),
      beforeUnmount: () => console.log('****beforeUnmount *****'),
      afterUnmount: () => console.log('-------afterUnmount *********---')

    });
  }
};

if (!window.qiankunStarted) {
  window.qiankunStarted = true;
  initQiankun();
  start({
    sandbox: {
      experimentalStyleIsolation: true, // 样式隔离
    },
  });
}

// 全局的未捕获异常处理器
addGlobalUncaughtErrorHandler(event => {
  console.log('异常=>', event)
})

</script>

<template>
  <div>
    <nav>
      <RouterLink to="/">首页</RouterLink> |
      <RouterLink to="/about">关于</RouterLink>
    </nav>
    <RouterView />

    <div id="container"></div>

  </div>
</template>

<style scoped>
nav {
  padding: 20px;
}
nav a {
  color: #42b883;
  text-decoration: none;
}
nav a.router-link-active {
  font-weight: bold;
}
</style>

registerMicroApps 这个方法重要,需要注册一下你的子应用

然后配置app1

app1是react 项目

需要有个注意点

qiankun 必须通过 UMD + 全局变量,才能"拿到"你的子应用并调用它的生命周期。

app1 的package.json 配置

修改下端口是8002 启动

使用react-app-rewired 进行webpack5改写

之后新建下config-overrides.js这个文件

javascript 复制代码
const { name } = require('./package.json')

module.exports = {
  webpack: (config) => {
    config.output.library = `${name}-[name]`
    config.output.libraryTarget = 'umd'
    config.output.globalObject = 'window'

    // ✅ webpack 5 专用
    config.output.chunkLoadingGlobal = `webpackJsonp_${name}`

    return config
  },

  devServer: (configFunction) => {
    return (proxy, allowedHost) => {
      const devConfig = configFunction(proxy, allowedHost)
      devConfig.headers = {
        'Access-Control-Allow-Origin': '*',
      }
      devConfig.historyApiFallback = true
      return devConfig
    }
  },
}

让qiankun框架可以进行跨域拉取app1这个应用的资源,不配置浏览器会拦截掉

然后新建一下public-path.js这样一个文件

javascript 复制代码
if (window.__POWERED_BY_QIANKUN__) {
  // eslint-disable-next-line no-undef
  __webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__
}

写这一段让主应用可以访问到子应用的资源文件比如图片,视频什么的

不写的话

http://localhost:3001/static/js/main.xxx.jpg 这个会拿不到

然后修改index.js

javascript 复制代码
import './public-path.js'
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';


let root = null

async function render(props) {
  const {container} = props
  root = root || ReactDOM.createRoot(
    container ? container.querySelector('#root'):document.getElementById('root')
  )
  
  root.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>
);

}

// const root = ReactDOM.createRoot(document.getElementById('root'));

if(!window.__POWERED_BY_QIANKUN__){
  render({})
}


export async function bootstrap() {
  console.log('[app2] bootstrap')
}

export async function mount(props) {
  console.log('[app2] mount', props)
  render(props)
}

export async function unmount() {
  console.log('[app2] unmount')
  if (root) {
    root.unmount()
    root = null
  }
}

// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();

这个导入一下重要,需要让上面的写法生效

这三个是qiankun的生命周期,后续需要和主应用通信什么的的可以用到

好了

接下来配置app2 子应用

app2是一个vue3项目

首先对vue.config.js 配置下

javascript 复制代码
const { defineConfig } = require('@vue/cli-service')
module.exports = defineConfig({
  transpileDependencies: true,
  devServer: {
    port: 8003,
    headers: {
      'Access-Control-Allow-Origin': '*',
    },
  },
   configureWebpack: {
    output: {
      library: 'app2',
      libraryTarget: 'umd',
      chunkLoadingGlobal: 'webpackJsonp-app2',
    },
  },
})

端口改8003 使用umd输出

然后就是main.js 配置

javascript 复制代码
import { createApp } from 'vue'
import App from './App.vue'

let app = null

function render(props = {}) {
  const { container } = props
  app = createApp(App)
  app.mount(container ? container.querySelector('#app') : '#app')
}

if (!window.__POWERED_BY_QIANKUN__) {
  render({})
}

export async function bootstrap() {
  console.log('[app2] bootstrap')
}

export async function mount(props) {
  console.log('[app2] mount', props)
  render(props)
}

export async function unmount() {
  console.log('[app2] unmount')
  if (app) {
    app.unmount()
    app = null
  }
}

最后就是进入 main-app

pnpm dev

启动应用

进入app1和app2 启动应用

效果如下

http://localhost:5173/app-vue

相关推荐
CodeSheep1 小时前
南京IT公司六小龙
前端·后端·程序员
IT_陈寒2 小时前
React useEffect依赖数组把我坑惨了,这次搞明白了
前端·人工智能·后端
gcw10242 小时前
Cron专业工具:定时任务与开发办公的一站式在线工具箱
java·前端·数据库·工具·crontab·cron·spring cron
环境栈笔记2 小时前
AI 浏览器任务失败怎么排查:Context、Session、Page State 和 Task Log 检查清单
前端·人工智能·后端·自动化
阳光是sunny2 小时前
别再让 AI 瞎找代码了!CodeGraph 这工具能让它秒懂你的项目
前端·后端·ai编程
tuddy7894642 小时前
快速创建常见的数据模型、CRUD 接口、配置文件等重复性结构
前端
小流苏生2 小时前
这是一篇关于忘记的文章
前端·程序员·ai编程
2601_963771372 小时前
Scaling Podcast RSS Feeds and Audio Streaming on WordPress Servers
前端·windows·php
名字还没想好☜5 小时前
Next.js App Router 数据获取:fetch 缓存、revalidate 与 dynamic 一次讲清
前端