自学内容网 自学内容网

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

$ yarn add qiankun # 或者 npm i qiankun -S

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

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:

if (window.__POWERED_BY_QIANKUN__) {
  __webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__;
}

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

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,修改并导出三个生命周期函数。

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 打包。

// 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

npm install vite-plugin-qiankun

2.修改vite.config.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.路由配置

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

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

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

拿着 不谢 请叫我“锤” !!!


原文地址:https://blog.csdn.net/hammer1010/article/details/143081780

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!