1、创建主应用:
npx vue create main-vue3-app
2、安装qiankun
npx yarn add qiankun
3、项目中使用的vue、vue-router、qiankun依赖如下,webpack版本为5.x
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
- <template>
- <nav>
- <router-link to="/">Homerouter-link> |
- <router-link to="/vue2-webpack-app">wepback+vue2Approuter-link> |
- <router-link to="/vue3-vite-app">vite+vue3Approuter-link> |
- <router-link to="/vue3-webpack-app">wepback+vue3Approuter-link> |
- <router-link to="/react-webpack-app">wepback+reactApprouter-link> |
- <router-link to="/react-vite-app">vite+reactApprouter-link>
-
-
-
- nav>
- <router-view/>
- template>
-
- <style>
- #app {
- font-family: Avenir, Helvetica, Arial, sans-serif;
- -webkit-font-smoothing: antialiased;
- -moz-osx-font-smoothing: grayscale;
- text-align: center;
- color: #2c3e50;
- }
-
- nav {
- padding: 30px;
- }
-
- nav a {
- font-weight: bold;
- color: #2c3e50;
- }
-
- nav a.router-link-exact-active {
- color: #42b983;
- }
- style>
6、然后创建微应用对应的路由页面以及注册微应用
router.ts
- import { createRouter, createWebHistory, RouteRecordRaw } from 'vue-router'
-
-
- const routes: Array<RouteRecordRaw> = [
- {
- 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')
- },
- {
- path: '/react-vite-app/:chapters*',
- name: 'react-vite-app',
- component: () => import('../views/ReactVite.vue')
- }
- ]
-
- const router = createRouter({
- history: createWebHistory(),
- routes
- })
-
- export default router
1、在主应用下创建对应的路由页面 views/Vue2App.vue
- <template>
- <div id="vue2-webpack-app"/>
- template>
-
- <script setup lang="ts">
- import { onMounted, ref } from 'vue';
- import { registerMicroApps, start } from 'qiankun';
-
- const loading = ref(false);
- registerMicroApps([
- {
- name: 'vue2-webpack-app',
- entry: '//localhost:8081/',
- container: '#vue2-webpack-app',
- activeRule: '/vue2-webpack-app',
-
- }
- ]);
- onMounted(() => {
- if (!window['qiankunStarted']) {
- window['qiankunStarted'] = true;
- start();
- }
- });
- script>
-
- <style scoped>style>
2、创建vue2+webpack项目,选2.x版本
npx vue create vue2-app
3、项目中使用的vue、vue-router依赖如下,webpack版本为5.x
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);
- }
-
1、在主应用下创建对应的路由页面 views/Vue3App.vue
- <template>
- <div id="vue3-webpack-app" />
- template>
-
- <script setup lang="ts">
- import { onMounted, ref } from 'vue';
- import { registerMicroApps, start } from 'qiankun';
-
- const loading = ref(false);
- registerMicroApps([
- {
- name: 'vue3-webpack-app',
- entry: '//localhost:8082/',
- container: '#vue3-webpack-app',
- activeRule: '/vue3-webpack-app',
-
- }
- ]);
- onMounted(() => {
- if (!window['qiankunStarted']) {
- window['qiankunStarted'] = true;
- start({
- prefetch:false,
- sandbox:{experimentalStyleIsolation:true}
- });
- }
- });
- script>
-
- <style scoped>style>
2、创建vue3+webpack项目,选3.x版本
npx vue create vue3-webpack-app
3、项目中使用的vue、vue-router依赖如下,webpack版本为5.x
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<RouteRecordRaw> = [
- {
- 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);
- }
1、在主应用下创建对应的路由页面 views/ViteApp.vue
- <template>
- <div id="vue3-vite-app" />
- template>
-
- <script setup lang="ts">
- import { onMounted, ref } from 'vue';
- import { registerMicroApps, start } from 'qiankun';
-
- const loading = ref(false);
- registerMicroApps([
- {
- name: 'vue3-vite-app',
- entry: '//localhost:5174/',
- container: '#vue3-vite-app',
- activeRule: '/vue3-vite-app',
-
- }
- ]);
- onMounted(() => {
- if (!window['qiankunStarted']) {
- window['qiankunStarted'] = true;
- start();
- }
- });
- script>
-
- <style scoped>style>
2、创建vue3+vite项目
npx pnpm create vite vue3-vite-app --template vue-ts
3、项目中使用的vue、vue-router依赖如下,vite版本为4.x
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
- })],
- server:{
- host: '127.0.0.1',
- port: 5174,
- }
-
- })
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();
- }
- });
- }
-
-
1、在主应用下创建对应的路由页面 views/ReactWebpack.vue
- <template>
- <div id="react-webpack-app"/>
- template>
-
- <script setup lang="ts">
- import { onMounted, ref } from 'vue';
- import { registerMicroApps, start } from 'qiankun';
-
- const loading = ref(false);
- registerMicroApps([
- {
- name: 'react-webpack-app',
- entry: '//localhost:3000/',
- container: '#react-webpack-app',
- activeRule: '/react-webpack-app',
- props: {
-
- }
- }
- ]);
- onMounted(() => {
- if (!window['qiankunStarted']) {
- window['qiankunStarted'] = true;
- start();
- }
- });
- script>
-
- <style scoped>style>
2、创建React+Webpack项目
npx create-react-app react-app
3、项目中使用的react、react-dom、react-router-dom依赖如下,webpack版本为5.x
4、创建config-overrides.js,修改配置
npm i react-scripts
修改package.json
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包裹,配置路由
- <Routes >
- <Route element={<Home/>} path='/'>Route>
- Routes>
- )
- }
6、在App.jsx中引入路由组件
- import Router from './router/index'
- import './App.css';
- function App() {
- return (
- <div>
- <Router>Router>
- div>
- );
- }
- 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(
- <BrowserRouter basename={window.__POWERED_BY_QIANKUN__ ? "/react-webpack-app" : "/"}>
- <React.StrictMode>
- <App />
- React.StrictMode>
- BrowserRouter>
- );
- }
-
- 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();
1、在主应用下创建对应的路由页面 views/ReactVite.vue
- <template>
- <div id="react-vite-app"/>
- template>
-
- <script setup lang="ts">
- import { onMounted, ref } from 'vue';
- import { registerMicroApps, start } from 'qiankun';
-
- const loading = ref(false);
- registerMicroApps([
- {
- name: 'react-vite-app',
- entry: '//localhost:5175/',
- container: '#react-vite-app',
- activeRule: '/react-vite-app',
-
- }
- ]);
- onMounted(() => {
- if (!window['qiankunStarted']) {
- window['qiankunStarted'] = true;
- start();
- }
- });
- script>
-
- <style scoped>style>
2、创建React18+vite项目
npx pnpm create vite react-vite-app --template react-ts
3、项目中使用的react、react-dom 、react-router-dom依赖如下,vite版本为4.x
4、安装vite-plugin-qiankun插件
npx pnpm add vite-plugin-qiankun
在vite.config.ts使用
- import { defineConfig } from 'vite'
- import react from '@vitejs/plugin-react'
- import qiankun from 'vite-plugin-qiankun'
-
-
- export default defineConfig({
- plugins: [
- // 在开发模式下需要把react()关掉
- // https://github.com/umijs/qiankun/issues/1257
- // react(),
- qiankun('react-vite-app', { // 微应用名字,与主应用注册的微应用名字保持一致
- useDevMode: true
- })
- ],
- server: {
- host: '127.0.0.1',
- port: 5175,
- }
- })
5、封装路由组件,src/router/index.tsx
- import React from 'react'
-
- import Home from '../views/home'
- // 导入路由依赖
- import { Route,Routes} from 'react-router-dom'
-
- export default function Router(){
- return (
- // 使用BrowserRouter包裹,配置路由
- <Routes >
- <Route element={<Home/>} path='/'>Route>
- Routes>
- )
- }
6、在App.tsx中引入路由组件
- import Router from './router/index'
- import React from 'react';
- import './App.css';
- function App() {
- return (
- <div>
- <Router>Router>
- div>
- );
- }
- export default App;
7、main.tsx入口
- import React from 'react'
- import ReactDOM from 'react-dom/client'
- import App from './App'
- import { BrowserRouter } from 'react-router-dom'
-
- import { renderWithQiankun, qiankunWindow } from 'vite-plugin-qiankun/dist/helper'
- let root:any;
-
- const render = (container:HTMLElement | undefined) => {
- // 如果是在主应用的环境下就挂载主应用的节点,否则挂载到本地
-
- root = root || ReactDOM.createRoot(container ? container.querySelector("#root") : document.getElementById("root") );
- console.log(qiankunWindow.__POWERED_BY_QIANKUN__)
- root.render(
- <BrowserRouter basename={qiankunWindow.__POWERED_BY_QIANKUN__ ? "/react-vite-app" : "/"}>
- <React.StrictMode>
- <App />
- React.StrictMode>
- BrowserRouter>
- );
- }
-
- const initQianKun = () => {
- renderWithQiankun({
- // 当前应用在主应用中的生命周期
- // 文档 https://qiankun.umijs.org/zh/guide/getting-started#
-
- mount(props) {
- render(props.container)
- // 可以通过props读取主应用的参数:msg
- // 监听主应用传值
- props.onGlobalStateChange((res) => {
- console.log(res.count)
- })
- },
- bootstrap() { },
- unmount() {
- root.unmount();
- root = null
- },
- })
- }
-
-
- // 判断当前应用是否在主应用中
- qiankunWindow.__POWERED_BY_QIANKUN__ ? initQianKun() : render(undefined)
20231027-120328
发现使用webpack构建的微应用,不支持路由懒加载的写法,vite就可以