qiankun:vite/webpack项目配置

news2024/11/17 13:51:17

相关博文:
https://juejin.cn/post/7216536069285429285?searchId=202403091501088BACFF113F980BA3B5F3

https://www.bilibili.com/video/BV12T411q7dq/?spm_id_from=333.337.search-card.all.click

qiankun结构:

主应用base:vue3+history+vite
子应用sub-react:react+history+webpack
子应用sub-vue:vue3+history+vite
子应用sub-vue2:vue2+base+webpack
在这里插入图片描述



❀ 主应用base

1、安装qiankun

yarn add qiankun # 或者 npm i qiankun -S

2、存放子应用信息

/src/utils/qiankun-config.js

export default {
    subApps: [
      {
        name: 'sub-react', // 子应用名称,跟package.json一致
        
        entry: process.env.NODE_ENV === 'development'
        ? '//localhost:3101'
        : '//react.qk.com', // 子应用入口,本地环境下指定端口
        container: '#sub-app', // 挂载子应用的dom
        activeRule: '/sub-react', // 路由匹配规则
        props: {} // 主应用与子应用通信传值
      },
      {
        name: 'sub-vue',
        entry: process.env.NODE_ENV === 'development'
        ? '//localhost:3100'
        : '//vue3.qk.com',
        container: '#sub-app',
        activeRule: '/sub-vue',
        props: {}
      },
      {
        name: 'sub-vue2',
        entry: process.env.NODE_ENV === 'development'
        ? '//localhost:3103'
        : '//vue2.qk.com',
        container: '#sub-app',
        activeRule: '/sub-vue2',
        props: {}
      }
    ]
  }

3、开启qiankun

/src/utils/qiankun

import { registerMicroApps, initGlobalState } from 'qiankun'
import config from './qiankun-config'

const { subApps } = config

export function registerApps() {
  try {
    registerMicroApps(subApps, {
      beforeLoad: [
        app => {
          console.log('before load', app)
          return Promise.resolve()
        }
      ],
      beforeMount: [
        app => {
          console.log('before mount', app)
          return Promise.resolve()
        }
      ],
      afterUnmount: [
        app => {
          console.log('before unmount', app)
          return Promise.resolve()
        }
      ]
    })
    const actions = initGlobalState(state);
    // 主项目项目监听和修改
    actions.onGlobalStateChange((state, prev) => {
      // state: 变更后的状态; prev 变更前的状态
      console.log('主项目项目监听变化:',state, prev);
    });
    actions.setGlobalState(state);
  } catch (err) {
    console.log('qiankunError',err)
  }
}

4、新建一个组件,用于加载子应用

/src/page/container.vue

<template>
    <div id="sub-app"></div>
</template>
  
<script lang="ts">
import { start } from 'qiankun'
import { registerApps } from '@/utils/qiankun'
  export default {
    mounted() {
      if (!window.__POWERED_BY_QIANKUN__) {
        window.qiankunStarted = true
        registerApps();
        start({
          sandbox: {
            experimentalStyleIsolation: true // 样式隔离
          }
        })
      }else{
        window.__POWERED_BY_QIANKUN__.on('mount', loadMicroApps);  如果一个页面同时展示多个微应用,需要使用 loadMicroApp 来加载。
      }
    }
  }
</script>

5、配置路由

export const router = createRouter({
  history: createWebHistory(),
  routes: [
    {
      path: '/',
      redirect: '/home',
      meta: {
        show: false
      }
    },
    {
      path: '/home',
      name: 'home',
      meta: {
        cnName: '首页',
        show: true
      },
      component: () => import('@/page/home.vue')
    },
    {
      path: '/about',
      name: 'about',
      meta: {
        cnName: '关于',
        show: true,
        keepAlive: true
      },
      component: () => import('@/page/about.vue')
    },
    {
      path: '/news/:id/:title/:content',
      name: 'news',
      meta: {
        cnName: '新闻',
        show: true
      },
      component: () => import('@/page/news.vue')
    },
    {
      path: '/communication',
      name: 'communication',
      meta: {
        cnName: '练习',
        show: true
      },
      component: () => import('@/page/communication.vue')
    },
    {
      // history模式需要通配所有路由,详见vue-router文档
      path: '/sub-react/:pathMatch(.*)*',
      name: 'sub-react',
      meta: {
        path:'/sub-react', // 注意:meta里的这个path是用来供router-link使用的,不用上面的path是因为点击主应用菜单跳转到子应用的时候默认带上了通配符
        cnName: 'sub-react',
        show: true,
        key: 'sub-react',
      },
      component: () => import('@/page/container.vue'),
    },
    {
      // history模式需要通配所有路由,详见vue-router文档
      path: '/sub-vue/:pathMatch(.*)*',
      name: 'sub-vue',
      meta: {
        path:'/sub-vue',
        cnName: 'sub-vue',
        show: true,
        key: 'sub-vue',
      },
      component: () => import('@/page/container.vue'),
    }
    ,
    {
      path: '/sub-vue2',
      name: 'sub-vue2',
      meta: {
        path:'/sub-vue2/', // 如果不加上最后的“/”,则域名会变成:http://localhost:8080/sub-vue2#/login
        cnName: 'sub-vue2',
        show: true,
        key: 'sub-vue2',
      },
      component: () => import('@/page/container.vue'),
    }
  ]
})

*注意:meta里的这个path是用来供router-link使用的,不用上面的path是因为点击主应用菜单跳转到子应用的时候默认带上了通配符
在这里插入图片描述

6、首页 src/App.vue 放置 router-view

<template>
	<header>
	    <router-link
	      v-for="item in routes"
	      :key="item.path"
	      :to="item.meta.path ? item.meta.path : item.path"
	    >
	      <span>{{ item.meta?.cnName }}</span>
	    </router-link>
	
		<router-view v-slot="{Component}" v-show="!$route.meta.key">
	      <keep-alive>
	        <component :is="Component" v-if="$route.meta.keepAlive" />
	      </keep-alive>
	      <component :is="Component" v-if="!$route.meta.keepAlive" />
	    </router-view>
	</header>
</template>


❀ vite子应用配置(sub-vue)

一、安装vite-plugin-qiankun(vue项目才需要安装)

npm i vite-plugin-qiankun --save-dev

二、修改vite.config.js

sub-vue 修改vite.config.js

export default defineConfig({
  // base: '/sub-vue',
  plugins: [
    vue(),
    vueJsx(),
    qiankun('sub-vue', {   // 配置qiankun插件
      useDevMode: true
    }),
  ],
  server: {
    host: 'localhost',
    port: 3100,
    origin: 'http://localhost:3100/',
    headers: {
      'Access-Control-Allow-Origin': '*'
    }
  }
})


❀ webpack子应用配置(sub-react、sub-vue2)

一、修改webpack配置文件

sub-react

// 在根目录下新增config-overrides.js文件并新增如下配置
const { name } = require("./package");

module.exports = {
  webpack: (config) => {
    config.output.library = `sub-react`;
    config.output.libraryTarget = "umd";
    config.output.chunkLoadingGlobal = `webpackJsonp_${name}`;
    return config;
  },
   devServer: (_) => {
    const config = _;
    // config.publicPath = "http://loaclhost:3101";
    
    config.headers = {
      'Access-Control-Allow-Origin': '*',
    };
    
    return config;
  },
};

sub-vue2

const { name } = require('./package.json')
const { defineConfig } = require('@vue/cli-service')
module.exports = defineConfig({
  transpileDependencies: true,
  configureWebpack: {
    output: {
      library: `sub-vue2`,
      libraryTarget: 'umd', // 把微应用打包成 umd 库格式
      // jsonpFunction: `webpackJsonp_${name}`,  // webpack5没有jsonpFunction这个options
      chunkLoadingGlobal: `webpackJsonp_${name}`
    },
  },
  devServer:{
    host: 'localhost',
    port: 3103,
    headers: {
      'Access-Control-Allow-Origin': '*',
    }
  }
})

二、配置public-path(解决子应用图片默认取主应用的路径)

sub-reactsub-vue2 src文件下添加public-path.js

if (window.__POWERED_BY_QIANKUN__) {
    // eslint-disable-next-line no-undef
    __webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__
}

并在入口文件的第一行!!!引入它
sub-react——src——index.js
在这里插入图片描述
sub-vue2——src——main.js
在这里插入图片描述

❀ history路由入口规则(sub-vue、sub-react)

sub-vue

import { createRouter, createWebHistory } from 'vue-router'
import { qiankunWindow } from 'vite-plugin-qiankun/dist/helper'

const routes = [
  {
    path: '/',
    redirect: { name: 'List' },
    meta: { title: '首页' },
    children: [
      {
        path: '/list',
        name: 'List',
        component: () => import('../views/List.vue')
      },
      {
        path: '/detail',
        name: 'Detail',
        component: () => import('../views/Detail.vue')
      }
    ]
  },
]

const router = createRouter({
  history: createWebHistory(qiankunWindow.__POWERED_BY_QIANKUN__ ? '/sub-vue/' : '/'),
  routes
})

export default router

sub-react好像不需要配置,直接在App.js添加router和link

<div className='menu'>
	<Link to={'/'}>list</Link>
	<Link to={'/detail'}>detail</Link>
	<a onClick={goVue}>vue列表页</a>
</div>
<Routes>
	<Route path='/' element={<List />} />
	<Route path='/detail' element={<Detail />} />
</Routes>

❀ 配置生命周期(所有子组件)

sub-react——src——index.js

import './public-path.js'   // public-path处理子应用里的图片地址默认取主应用的路径
import React from 'react';
import { createRoot } from 'react-dom/client';
import './index.css';

import App from './App';
import { BrowserRouter } from 'react-router-dom'
import reportWebVitals from './reportWebVitals';

let root;
// 将render方法用函数包裹,供后续主应用与独立运行调用
function render(props) {
  const { container } = props
  const dom = container ? container.querySelector('#root') : document.getElementById('root')
  root = createRoot(dom)
  if(!container){
    root.render(
      <BrowserRouter>
        <App/>
      </BrowserRouter>
    )
    return
  }
  root.render(
    <BrowserRouter basename='/sub-react'>   // 设置路由base
      <App/>
    </BrowserRouter>
  )
}

// 判断是否在qiankun环境下,非qiankun环境下独立运行
if (!window.__POWERED_BY_QIANKUN__) {
  render({});
}

// 各个生命周期
// bootstrap 只会在微应用初始化的时候调用一次,下次微应用重新进入时会直接调用 mount 钩子,不会再重复触发 bootstrap。
export async function bootstrap() {
  console.log('react app bootstraped');
}

// 应用每次进入都会调用 mount 方法,通常我们在这里触发应用的渲染方法
export async function mount(props) {
  render(props);
}

// 应用每次 切出/卸载 会调用的方法,通常在这里我们会卸载微应用的应用实例
export async function unmount(props) {
  root.unmount();
}


// 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();

sub-vue——src——main.js

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

let app:any

const render = (container) => {
  app = createApp(App)
  app
    .use(router)
    .mount(container ? container.querySelector('#app') : '#app')
}

const initQianKun = () => {
  renderWithQiankun({
    mount(props) {
      const { container } = props
      render(container)
    },
    bootstrap() {},
    unmount() {
      app.unmount()
    }
  })
}

qiankunWindow.__POWERED_BY_QIANKUN__ ? initQianKun() : render()

sub-vue2——src——main.js

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

Vue.config.productionTip = false

let instance = null

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

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

export async function bootstrap() {
  console.log(' vue2 app bootstraped')
}
export async function mount(props) {
  console.log(' props from main framework', props);
  render(props)
}
export async function unmount() {
  instance.$destroy()
  instance.$el.innerHTML = ''
  instance = null
}

❀ 踩坑点:

子应用切换时出现以下警告:(我没遇到)
在这里插入图片描述
主应用增加:

router.beforeEach((to, from, next) => {
  if (!window.history.state.current) window.history.state.current = to.fullPath
  if (!window.history.state.back) window.history.state.back = from.fullPath
  // 手动修改history的state
  return next()
})

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1515346.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

通过Maven创建Web工程

通过Maven创建Web工程 方式一方式二 方式一 1.先创建一个Maven工程 2.把该Maven模块的pom文件里添加一个war 3.选中该Maven模块 点击项目架构 4.手动添加一个Web架构 方式二 1.也是new一个模块 但是直接配置好Web 2.这里就是我IDEA对Maven的设置 3.第一次创建 可能…

JavaEE框架学习笔记——Mybatis篇

四、一级缓存 五、二级缓存 一、Mybatis的Dao编写【mapper代理方式实现】 Mapper代理的开发方式&#xff0c;程序员只需要编写mapper接口&#xff08;相当于dao接口&#xff09;即可。Mybatis会自动的为mapper接口生成动态代理实现类。不过要实现mapper代理的开发方式****&am…

酷开科技大内容战略,打破时间和空间的限制畅快追剧!

随着科技的发展&#xff0c;电视作为家庭娱乐中心设备的角色正在发生改变&#xff0c;它不仅仅 是家庭的娱乐中心&#xff0c;更是成为连接家庭智能家居的中心枢纽&#xff0c;为家庭带来更为丰富和个性化的娱乐体验。深耕大屏十余年&#xff0c;酷开科技通过技术上的不断突破和…

nacos做注册注册中心go语言实战教程(服务的注册与获取)

背景 随着访问量的逐渐增大&#xff0c;单体应用结构渐渐不满足需求&#xff0c;在微服务出现之后引用被拆分为一个个的服务&#xff0c;服务之间可以互相访问。初期服务之间的调用只要知道服务地址和端口即可&#xff0c;而服务会出现增减、故障、升级等变化导致端口和ip也变…

LeetCode Python - 51. N 皇后

目录 题目答案运行结果 题目 按照国际象棋的规则&#xff0c;皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子。 n 皇后问题 研究的是如何将 n 个皇后放置在 nn 的棋盘上&#xff0c;并且使皇后彼此之间不能相互攻击。 给你一个整数 n &#xff0c;返回所有不同的 n …

深度学习——SAM(Segment-Anything)代码详解

目录 引言代码目录segment-anything 代码详解build_sam.pypredictor.pyautomatic_mask_generator.py 引言 从去年年初至今&#xff0c;SAM(Segment Anything )已经问世快一年了&#xff0c;SAM凭借其强大而突出的泛化性能在各项任务上取得了优异的表现&#xff0c;广大的研究者…

ChromeDriver 122 版本为例 国内下载地址及安装教程

ChromeDriver 国内下载地址 https://chromedriver.com/download 靠谱 千千万万别下载错了 先确认 Chrome 浏览器版本 以 win64 版本为例 那我们下载这一个啊&#xff0c;不要下载错了 下载地址贴在这哈 https://storage.googleapis.com/chrome-for-testing-public/122.0.…

linux安全--CentOS7安装Tomcat,远程管理ManagerApp

目录 1.Tomcat安装 2.Tomcat远程管理 1.Tomcat安装 下载安装包并解压 tar xf apache-tomcat-7.0.54.tar.gz -C /usr/local/apache-tomcat_7.0.54/tomcat启停 启动 ./startup.sh 停止 ./shutdown.sh 2.Tomcat远程管理 找到tomcat文件夹中webapps/manager/META-INF/contex…

IDEA中导入eclipse运行的java项目

本篇文章主要的内容是在IDEA中导入eclipse运行的java项目&#xff0c;亲测有效。 话不多说&#xff0c;直接开整。 前提&#xff1a;先打开idea软件&#xff0c;界面如下&#xff1a; 开始按下方步骤依次走即可。 1、file --> new --> Project from Existing Sources..…

OPPO后端二面,凉了!

这篇文章的问题来源于一个读者之前分享的 OPPO 后端凉经&#xff0c;我对比较典型的一些问题进行了分类并给出了详细的参考答案。希望能对正在参加面试的朋友们能够有点帮助&#xff01; Java String 为什么是不可变的? public final class String implements java.io.Seri…

C++提高笔记(三)---STL容器(vector、deque)

1、vector容器 1.1vector基本概念 功能&#xff1a;vector数据结构和数组非常相似&#xff0c;也称为单端数组 vector与普通数组区别&#xff1a;不同之处在于数组是静态空间&#xff0c;而vector可以动态扩展 动态扩展&#xff1a;并不是在原空间之后续接新空间&#xff0…

ES6(三):Iterator、Generator、类的用法、类的继承

一、迭代器Iterator 迭代器是访问数据的一个接口&#xff0c;是用于遍历数据结构的一个指针&#xff0c;迭代器就是遍历器 const items[one,two,three];//创建新的迭代器const ititems[Symbol.iterator]();console.log(it.next()); done&#xff1a;返回false表示遍历继续&a…

Kafka MQ 生产者

Kafka MQ 生产者 生产者概览 尽管生产者 API 使用起来很简单&#xff0c;但消息的发送过程还是有点复杂的。图 3-1 展示了向 Kafka 发送消息的主要步骤。 我们从创建一个 ProducerRecord 对象开始&#xff0c;ProducerRecord 对象需要包含目标主题和要发送的内容。我们还可以…

linux命令深入研究——cat

cat命令&#xff0c;“猫”&#xff0c;可以理解为瞄一眼文件内容&#xff0c;其中可以用重定向符号对文件进行一些修改&#xff0c;如增加&#xff0c;删除文件内容&#xff0c;其命令参数如-n&#xff0c;-s&#xff0c;-b可以输出带有行号的行 如果想要快速删除文件内容&…

[全志T113]:Tina SDK安装

[全志T113]&#xff1a;Tina SDK安装 SDK安装与补丁 SDK下载地址 https://pan.baidu.com/s/1wxUeYQZaSgAPGorGOVcJxA?pwdtina 1.解压SDK tar -zxvf Tina-Linux-20220815.tar.gz cd Tina-Linux2.安装补丁&#xff1a; $ wget http://dl.mangopi.org/tina/prebuilt.tar.gz …

【数据结构】双向链表及LRU缓存的实现

目录 前言 1. 在原有的自定义链表类 Linked 的基础上&#xff0c;添加新的 “节点添加”方法 addNode(Node node) 测试用例 测试结果 2. 在自定义链表类的基础上&#xff0c;使用双重循环“强力” 判断两个节点是否发生相交 测试用例 测试结果 3. 在自定义链表类的基础上…

Linux基础开发工具之yum与vim

1. Linux软件包管理器——yum 1.1 什么是软件包&#xff1f; 在Linux下安装软件, 一个通常的办法是下载到程序的源代码, 并进行编译, 得到可执行程序. 但是这样太麻烦了, 于是有些人把一些常用的软件提前编译好, 做成软件包(可以理解成windows上的安装程序)放在一个服务器上, …

JavaWeb06-MVC和三层架构

目录 一、MVC模式 1.概述 2.好处 二、三层架构 1.概述 三、MVC与三层架构 四、练习 一、MVC模式 1.概述 MVC是一种分层开发的模式&#xff0c;其中 M&#xff1a;Model&#xff0c;业务模型&#xff0c;处理业务 V&#xff1a; View&#xff0c;视图&#xff0c;界面展…

浅谈HTTP 和 HTTPS (中间人问题)

前言 由于之前的文章已经介绍过了HTTP , 这篇文章介绍 HTTPS 相对于 HTTP 做出的改进 开门见山: HTTPS 是对 HTTP 的加强版 主要是对一些关键信息 进行了加密 一.两种加密方式 1.对称加密 公钥 明文 密文 密文 公钥 明文 2.非对称加密 举个例子就好比 小区邮箱 提供一…

学习SSM的记录(八)-- SSM整合项目《任务列表案例》

前端程序搭建和运行 项目预览 接口分析 1.学习计划分页查询 需求&#xff1a;查询对应数据页数据 uri&#xff1a;schedule/{pageSize}/{currentPage} 请求方式&#xff1a;get 响应数据&#xff1a;json {"code":200,"flag":true,"data"…