vue3+vite5+qiankun结合vite-plugin-qiankun插件,搭建微前端框架

vue3+vite5+qiankun结合vite-plugin-qiankun插件,搭建微前端框架

没有特别的幸运,那么就特别的努力!!!

前言

涉及到环境

npm:9.6.3

node:19.9.0

node官网地下载址:https://nodejs.org/dist

项目框架

主应用:vue2

微应用1:vue2,qiankun官网API是基于vue2+webpack。

微应用2:vue3+vite+ts,目前官网没有vue3示例,需要介入vite-plugin-qiankun插件进行处理

下面是用qiankun简易搭建的demo效果图:

主应用

第一步:安装qiankun

js 复制代码
$ yarn add qiankun # 或者 npm i qiankun -S

第二步:主应用中注册微应用

js 复制代码
import Vue from 'vue'
import App from './App.vue'
import router from './router'

import { registerMicroApps, start } from 'qiankun' //新增部分,导入qiankun中的两个方法
const apps = [
    {
        name: 'vue2App', //子应用的名称
        entry: 'http://192.168.1.12:8083/#/', //子应用的域名,改成自己对应的ip即可
        container: '#vue', //承载子应用的容器,在上面App.vue中定义
        activeRule: '/vue', // 被激活的子应用的路由
    },
    {
        name: 'vue3App', //子应用的名称
        entry: 'http://192.168.1.12:8089/#/', //子应用的域名
        container: '#vue', //承载子应用的容器,在上面App.vue中定义
        activeRule: '/main', // 被激活的子应用的路由
    },
]
registerMicroApps(apps); //注册子应用
start(); //启动qiankun

new Vue({
    router,
    render: h => h(App)
}).$mount('#app');

微应用

微应用1:vue2+webpack

微应用分为有 webpack 构建,需要做的事情如下:

步骤 说明
1 新增 public-path.js 文件,用于修改运行时的 publicPath。
2 微应用建议使用 history 模式的路由,需要设置路由 base,值和它的 activeRule 是一样的。
3 在入口文件最顶部引入 public-path.js,修改并导出三个生命周期函数。
4 修改 webpack 打包,允许开发环境跨域和 umd 打包。

1.在 src 目录新增 public-path.js:

js 复制代码
if (window.__POWERED_BY_QIANKUN__) {
  __webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__;
}

2.微应用建议使用 history 模式的路由,需要设置路由 base,值和它的 activeRule 是一样的。

js 复制代码
import Vue from 'vue'
import VueRouter from 'vue-router'
import home from '../view/home.vue'
import '../public-path'

Vue.use(VueRouter)

const routes = [{
        path: '/home',
        name: 'home',
        component: home
    },
    {
        path: '/Dome',
        name: 'Dome',
     
        component: () =>
            import ( /* webpackChunkName: "about" */ '../view/About.vue')
    }
]

const router = new VueRouter({
    mode: 'history',
    base: window.__POWERED_BY_QIANKUN__ ? '/vue' : '/',
    routes
})

export default router

3.在入口文件最顶部引入 public-path.js,修改并导出三个生命周期函数。

js 复制代码
import 'babel-polyfill'
import 'core-js/stable'
import 'regenerator-runtime/runtime';
require('es6-promise').polyfill()
import Vue from 'vue'
import App from './App.vue'
import router from './router'
// import store from './store'

import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
Vue.use(ElementUI);

Vue.config.productionTip = false

let instance = null;

function render(props = {}) {
    const { container } = props;
    instance = new Vue({
        router,
        // store,
        render: h => h(App),
    }).$mount(container ? container.querySelector('#app') : '#app');
}
export async function mount(props) {
    render(props);
}

//判断当前运行环境是独立运行的还是在父应用里面进行运行,配置全局的公共资源路径
if (window.__POWERED_BY_QIANKUN__) {
    __webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__;
}
//如果是独立运行window.__POWERED_BY_QIANKUN__=undefined
if (!window.__POWERED_BY_QIANKUN__) {
    render()
}
//最后暴露的三个方法是固定的,加载渲染以及销毁
export async function bootstrap() {}
// export async function mount(props){
//     render();
// } 
export async function unmount() {
    instance.$destroy();
}
export async function update(props) {
      console.log('update props', props);
}

4.修改 webpack 打包,允许开发环境跨域和 umd 打包。

js 复制代码
// vue.config.js
module.exports = {
  lintOnSave: false,
  devServer: {
      port: 8083,
      headers: {
          "Access-Control-Allow-Origin": "*"
      }
  },
    transpileDependencies: ['*'], 
    configureWebpack: config => {
        config.entry.app = ['babel-polyfill', './src/main.js']
        return {
            output: {
                library: 'vueApp',
                libraryTarget: 'umd'
            }
        }
    }
}

微应用2:vue3+vite5

1.qiankun目前不支持vite,需要借助插件vite-plugin-qiankun

js 复制代码
npm install vite-plugin-qiankun

2.修改vite.config.js配置

js 复制代码
import { fileURLToPath, URL } from 'node:url'

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import qiankun from 'vite-plugin-qiankun'
// useDevMode 开启时与热更新插件冲突
const useDevMode = true // 如果是在主应用中加载子应用vite,必须打开这个,否则vite加载不成功, 单独运行没影响

// https://vite.dev/config/
export default defineConfig({
  plugins: [
    vue(),
    qiankun('vue3App', { // 微应用名字,与主应用注册的微应用名字保持一致
      useDevMode
    })
  ],
  base: '/main/',
  resolve: {
    alias: {
      '@': fileURLToPath(new URL('./src', import.meta.url))
    }
  },
  server: {
    host: "0.0.0.0",
    port: 8889, //这里的端口是必须和父应用配置的子应用端口一致
    headers: {
        //因为qiankun内部请求都是fetch来请求资源,所以子应用必须允许跨域
        'Access-Control-Allow-Origin': '*'
    },
    overlay: {
        warning: false,
        errors: false
    }
  },
  configureWebpack: {
    output: {
      library: `vue3App`,
      libraryTarget: 'umd', // 把微应用打包成 umd 库格式
      // jsonpFunction: `webpackJsonp_${name}`, // webpack 5 需要把 jsonpFunction 替换成 chunkLoadingGlobal
    },
  },
})

3.路由配置

js 复制代码
import { createRouter, createWebHistory } from 'vue-router'
import HomeView from '../views/HomeView.vue'
import {
  qiankunWindow,
} from 'vite-plugin-qiankun/dist/helper'

const router = createRouter({
  history: createWebHistory(import.meta.env.BASE_URL),
  base: qiankunWindow.__POWERED_BY_QIANKUN__ ? '/main' : '/',
  routes: [
    {
      path: '/',
      name: 'home',
      component: HomeView
    },
    {
      path: '/about',
      name: 'about',
      // route level code-splitting
      // this generates a separate chunk (About.[hash].js) for this route
      // which is lazy-loaded when the route is visited.
      component: () => import('../views/AboutView.vue')
    }
  ]
})

export default router

4.修改main.js

js 复制代码
import './assets/main.css'

import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import { renderWithQiankun, qiankunWindow} from 'vite-plugin-qiankun/dist/helper'

let instance = null

function render(props = {}) {
  instance = createApp(App) // 必须放到函数里面,否则会提示重新创建
  const { container } = props

  instance.use(router)
  //   instance.use(store);
  instance.mount(
    container ? container.querySelector('#app') : document.getElementById('app')
  )
  if (qiankunWindow.__POWERED_BY_QIANKUN__) {
    console.log('我正在作为子应用运行')
  }
}
// some code
renderWithQiankun({
  mount(props) {
    console.log('viteapp mount')
    render(props)
  },
  bootstrap() {
    console.log('bootstrap')
  },
  unmount(props) {
    console.log('vite被卸载了')
    instance.unmount()
    // instance._container.innerHTML = ''
    // history.destroy() // 不卸载  router 会导致其他应用路由失败
    // instance = null
  }
})

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

完整代码

https://gitee.com/hammer1010_admin/qiankun-cro.git

希望能帮助到大家,同时祝愿大家在开发旅途中愉快!!!

拿着 不谢 请叫我"锤" !!!

相关推荐
做前端的娜娜子1 小时前
同一链接实现 PC Web 与移动 H5 自适应
前端·掘金·金石计划
小帅不太帅1 小时前
架构没变、规模没变,DeepSeek V4 Flash 正式版凭什么暴涨 47 分?
前端·aigc·deepseek
jarvisuni2 小时前
DeepSeekFlash前端依旧拉垮,而且变慢了很多!
前端·javascript·算法
卷福同学3 小时前
AI编程出海第二步:验证关键词能否做站
前端·人工智能·后端
先吃饱再说3 小时前
编写一个颜色选择器之后,我理解了 React 工程化的三层架构
react.js·前端框架·前端工程化
先吃饱再说3 小时前
别说你懂 useEffect:从底层机制到生命周期管理,这篇全讲透了
react.js·前端框架
赵庆明老师3 小时前
Vben精讲:21-详解web-antd:tsconfig.json
前端·json·vim
先吃饱再说3 小时前
从“传事件”到“只传值”:React + TypeScript 组件 Props 设计的两次进化
react.js·前端框架·前端工程化
wc884 小时前
微软EDGE浏览器功能学习
前端·学习·edge