微前端qiankun接入Vue和React项目

主应用:Vue3+Webpack

1、创建主应用:

npx vue create main-vue3-app

2、安装qiankun

npx yarn add qiankun

3、项目中使用的vue、vue-router、qiankun依赖如下,webpack版本为5.x

微前端qiankun接入Vue和React项目_第1张图片

4、在根目录下创建vue.config.js

const { defineConfig } = require('@vue/cli-service');
const packageName = require('./package.json').name;
module.exports = defineConfig({
    lintOnSave: false,
    devServer: {
        // 可以在配置中 配置端口 VUE_APP_PORT = 8080
        port: 8080,
        headers: {
            'Access-Control-Allow-Origin': '*' // 允许跨域访问子应用页面
        }
    }
})

5、入口组件App.vue




6、然后创建微应用对应的路由页面以及注册微应用

router.ts

import { createRouter, createWebHistory, RouteRecordRaw } from 'vue-router'


const routes: Array = [
  {
    path: '/',
    name: 'index',
    component: () => import('../views/Index.vue')
  },
  {
    path: '/vue2-webpack-app/:chapters*',
    name: 'vue2-webpack-app',
    component: () => import('../views/Vue2App.vue')
  },
  {
    path: '/vue3-vite-app/:chapters*',
    name: 'vue3-vite-app',
    component: () => import('../views/ViteApp.vue')
  },
  {
    path: '/vue3-webpack-app/:chapters*',
    name: 'vue3-webpack-app',
    component: () => import('../views/Vue3App.vue')
  },
  {
    path: '/react-webpack-app/:chapters*',
    name: 'react-webpack-app',
    component: () => import('../views/ReactWebpack.vue')
  }
]

const router = createRouter({
  history: createWebHistory(),
  routes
})

export default router

微应用:Vue2+Webpack

1、在主应用下创建对应的路由页面 views/Vue2App.vue





2、创建vue2+webpack项目,选2.x版本

npx vue create vue2-app

3、项目中使用的vue、vue-router依赖如下,webpack版本为5.x

微前端qiankun接入Vue和React项目_第2张图片

4、在根目录下创建vue.config.js

const { defineConfig } = require('@vue/cli-service');
const packageName = require('./package.json').name;
module.exports = defineConfig({
    lintOnSave: false,
    devServer: {
        // 可以在配置中 配置端口 VUE_APP_PORT = 8080
        port: 8081,
        headers: {
            'Access-Control-Allow-Origin': '*' // 允许跨域访问子应用页面
        }
    },
    configureWebpack: {
        output: {
            library: `${packageName}-[name]`,
            libraryTarget: 'umd',
            chunkLoadingGlobal: `webpackJsonp_${packageName}`,
        },
    }
})

5、在src根目录下创建public-path.js

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

6、router/index.ts

import Vue from 'vue'
import VueRouter from 'vue-router'
import IndexVue from '../views/Index.vue'

Vue.use(VueRouter)

const routes= [
  {
    path: '/',
    name: 'index',
    component: IndexVue
    // component: () => import( '@/views/Index.vue')

  },
]
console.log(window.__POWERED_BY_QIANKUN__)
const router = new VueRouter({
  mode: 'history',
  base: window.__POWERED_BY_QIANKUN__ ? '/vue2-webpack-app' : '/',
  routes
})

export default router

7.入口文件main.ts/main.js

import Vue from 'vue'
import App from './App.vue'
import router from './router';
import './public-path'

Vue.config.productionTip = false
let instance:any = null;

function render(props:any = {}) {
  const { container } = props
  instance = new Vue({
    name: 'root',
    router,
    render: h => h(App)
  }).$mount(container ? container.querySelector('#app') : '#app')

}
 
if (!window.__POWERED_BY_QIANKUN__) {
  render()
}
/**
* bootstrap 只会在微应用初始化的时候调用一次,下次微应用重新进入时会直接调用 mount 钩子,不会再重复触发 bootstrap。
* 通常我们可以在这里做一些全局变量的初始化,比如不会在 unmount 阶段被销毁的应用级别的缓存等。
*/
export async function bootstrap() {
    console.log('vue2+webpack bootstraped');
}
 
/**
* 应用每次进入都会调用 mount 方法,通常我们在这里触发应用的渲染方法
*/
export async function mount(props:unknown) {
    // ReactDOM.render(, props.container ? props.container.querySelector('#root') : document.getElementById('root'));

    console.log('乾坤子应用容器加载完成,开始渲染 child')
    console.log('props from main mount', props)
    render(props)
}
 
/**
* 应用每次 切出/卸载 会调用的方法,通常在这里我们会卸载微应用的应用实例
*/
export async function unmount() {
  instance?.$destroy();

 
}
 
 
/**
* 可选生命周期钩子,仅使用 loadMicroApp 方式加载微应用时生效
*/
export async function update(props:unknown) {
    console.log('update props', props);
}

微应用:Vue3+Wepback

1、在主应用下创建对应的路由页面 views/Vue3App.vue





2、创建vue3+webpack项目,选3.x版本

npx vue create vue3-webpack-app

3、项目中使用的vue、vue-router依赖如下,webpack版本为5.x

微前端qiankun接入Vue和React项目_第3张图片

4、在根目录下创建vue.config.js

const { defineConfig } = require('@vue/cli-service');
const packageName = require('./package.json').name;
const path = require('path');
module.exports = defineConfig({
    lintOnSave: false,
    devServer: {
        // 可以在配置中 配置端口 VUE_APP_PORT = 8080
        port: 8082,
        headers: {
            'Access-Control-Allow-Origin': '*' // 允许跨域访问子应用页面
        }
    },
    configureWebpack: {
        output: {
            library: `${packageName}-[name]`,
            libraryTarget: 'umd',
            chunkLoadingGlobal: `webpackJsonp_${packageName}`,
        },
        resolve:{
            alias:{
                '@':path.join(__dirname,'src')
            }
        }
    }
})

5、在src根目录下创建public-path.js

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

6、router/index.ts

import { createRouter, createWebHistory, RouteRecordRaw } from 'vue-router'
import IndexView from '../views/Index.vue'

const routes: Array = [
  {
    path: '/',
    name: 'index',
    component: IndexView
    // component: () => import('../views/Index.vue')
  }
]

const router = createRouter({
  history: createWebHistory(window.__POWERED_BY_QIANKUN__?'/vue3-webpack-app':process.env.BASE_URL),
  routes
})

export default router

7.入口文件main.ts/main.js

import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import './public-path'

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


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

export async function bootstrap() {
    console.log('vue3+webpack bootstraped');
}

/**
* 应用每次进入都会调用 mount 方法,通常我们在这里触发应用的渲染方法
*/
export async function mount(props: unknown) {
    // ReactDOM.render(, props.container ? props.container.querySelector('#root') : document.getElementById('root'));

    console.log('乾坤子应用容器加载完成,开始渲染 child')
    console.log('props from main mount', props)
    render(props)
}

/**
* 应用每次 切出/卸载 会调用的方法,通常在这里我们会卸载微应用的应用实例
*/
export async function unmount() {
    console.log('unmount-------------------')
    app.unmount()
    app = null

}


/**
* 可选生命周期钩子,仅使用 loadMicroApp 方式加载微应用时生效
*/
export async function update(props: unknown) {
    console.log('update props', props);
}

微应用:Vue3+Vite

1、在主应用下创建对应的路由页面 views/ViteApp.vue





2、创建vue3+vite项目

npx pnpm create vite vue3-vite-app --template vue-ts

3、项目中使用的vue、vue-router依赖如下,vite版本为4.x

微前端qiankun接入Vue和React项目_第4张图片

4、安装vite-plugin-qiankun插件

npx pnpm add vite-plugin-qiankun

在vite.config.ts使用

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'

import qiankun from 'vite-plugin-qiankun';
// https://vitejs.dev/config/
export default defineConfig({
  plugins: [vue() ,qiankun('vue3-vite-app', {
    useDevMode: true
  }),],
 
})

5、router/index.ts

import { createRouter, createWebHistory } from 'vue-router'
import {

  qiankunWindow
} from 'vite-plugin-qiankun/dist/helper';

const router = createRouter({
  history: createWebHistory(qiankunWindow.__POWERED_BY_QIANKUN__ ? '/vue3-vite-app' : '/'),
  routes: [
    {
      path: '/',
      name: 'index',
      component: () => import(/* webpackChunkName: "index" */ '../views/Index.vue')
    }
  ]
})

export default router

6、在src根目录下创建public-path.js

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

7、main.ts



import { createApp } from 'vue'
import './public-path'


import App from './App.vue'
import router from './router'

import {
    renderWithQiankun,
    qiankunWindow
  } from 'vite-plugin-qiankun/dist/helper';
  
  let app:any;
  if (!qiankunWindow.__POWERED_BY_QIANKUN__) {
    createApp(App).use(router).mount('#app');
  } else {
    renderWithQiankun({
      mount(props) {
        console.log('--mount');
  console.log(props)
        app = createApp(App);
        app
          .use(router)
          .mount(
            (props.container
              ? props.container.querySelector('#app')
              : document.getElementById('app')) as Element
          );
      },
      bootstrap() {
        console.log('--bootstrap');
      },
      update() {
        console.log('--update');
      },
      unmount() {
        console.log('--unmount');
        app?.unmount();
      }
    });
  }
  

微应用:React 18+Webpack

1、在主应用下创建对应的路由页面 views/ReactWebpack.vue





2、创建React+Webpack项目

npx create-react-app react-app

3、项目中使用的react、react-dom、react-router-dom依赖如下,webpack版本为5.x

微前端qiankun接入Vue和React项目_第5张图片

4、创建config-overrides.js,修改配置

 npm i react-scripts

修改package.json

微前端qiankun接入Vue和React项目_第6张图片

5、封装路由组件,src/router/index.js

import React from 'react'

import Home from '../views/home'
// 导入路由依赖
import { Route,Routes} from 'react-router-dom'
 
export default function Router(){
    return (
        // 使用BrowserRouter包裹,配置路由
      
        } path='/'>
      
    )
}

6、在App.jsx中引入路由组件

import Router from './router/index'
import './App.css';
function App() {
  return (
    
); } export default App;

7、index.js入口

import React from 'react';
import ReactDOM from 'react-dom/client';
import { BrowserRouter } from 'react-router-dom'
import './index.css';
import App from './App';
import './public-path';
import reportWebVitals from './reportWebVitals';
// let root = createRoot(document.querySelector('#root'))
let root = null;
function render (props) {
    const { container } = props;
    root = root || ReactDOM.createRoot(container ? container.querySelector("#root") : document.getElementById("root") );
    root.render(
        
            
                
            
        
    );
}

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

export async function bootstrap () {
    console.log("[react18] react app bootstraped");
}

export async function mount (props) {
    console.log("[react18] props from main framework", props);
    render(props);
}

export async function unmount (props) {
    root.unmount();
    root = null;
}


reportWebVitals();

演示:

待上传

完整代码:

待上传

你可能感兴趣的:(前端,vue.js,react.js,qiankun)