qiankun集成主子应用之创建篇(详细说明了主子应用从环境到创建到运行全过程)

qiankun集成主子应用—创建全过程篇

前言

公司想要进行项目升级,把之前老套的淘汰的项目框架使用Vue3重写,并且后端也由.net5.0升级为8.0,还想把全部项目整合到一起,变成一个BS的大平台项目,由此引用微前端框架,我选择了qiankun,原因无他,看起来相比于其他框架简单。由于在使用qiankun过程中出现了不少问题,在此做下笔记。

项目环境选择

电脑运行环境:nodeJS ,下载地址:Node.js 。下载和安装环境略过。

项目环境我使用的是 Vite+Js+pinia。原因如下:

  1. Vite :Vue3支持的编译速度最快的构建器;
  2. JavaScript : 其实Js和Ts无所谓,如果习惯Ts写法推荐Ts,据说编译速度会更快;
  3. Pinia :Pinia有着更好的性能表现,并且管理状态的方式相对Vuex来说更加简单,就是插件没有Vuex丰富。

创建主应用

控制台输入命令:

npm create vite@latest

输入项目名称以及选择好相关的配置比如Vue和Js:
在这里插入图片描述
项目创建完成后将该应用作为主应用运行,当然你可以选择主应用为框架,其他子应用作为内容兼容进来。

安装相关插件(qiankun、pinia、路由等):
npm:

npm install qiankun -s
npm install pinia -s
npm install pinia-plugin-persistedstate -s
npm install vue-route -s
npm install element-plus --save
npm install -D unplugin-vue-components unplugin-auto-import //按需导入ElementPlus

修改一下Vite.config.js的项目运行配置,完整代码如下,其中引用了ElementPlus优化页面:

import { fileURLToPath, URL } from 'node:url'
import { defineConfig } from 'vite'
import AutoImport from 'unplugin-auto-import/vite'
import Components from 'unplugin-vue-components/vite'
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'
import vue from '@vitejs/plugin-vue'

// https://vite.dev/config/
export default defineConfig({
  plugins: [
    vue(),
    AutoImport({
      resolvers: [ElementPlusResolver()],
    }),
    Components({
      resolvers: [ElementPlusResolver()],
    }),
  ],
  server: {
    port: 5111,
    headers: {
      // 重点1: 允许跨域访问子应用页面
      'Access-Control-Allow-Origin': '*',
    },
  },
  resolve: {
    alias: {
      '@': fileURLToPath(new URL('./src', import.meta.url)),
    },
  },
})

主应用的main.js中添加代码,完整main.js如下,自行对比修改了哪些内容:

import { createApp } from 'vue'
import App from './App.vue'
import router from './router'

// 主应用入口文件 main.js 或者 app.js
import { registerMicroApps, start } from 'qiankun'

const app = createApp(App)
app.use(router)
app.mount('#mainApp') //修改挂载容器(包括index.html),建议主子应用都别用app,定义好不重复的名称,不然容易出现挂载异常

registerMicroApps(
  [
    {
      name: 'qiankun-subApp', // 子应用的名称
      entry: '//localhost:5555', // 子应用的入口地址
      container: '#qiankun-subApp', // 挂载的DOM元素
      activeRule: '/subHomePage', // 激活子应用的路由规则(子应用首次访问的路由地址)
    },
  ],
  {
    //还有一些生命周期 如果需要可以根据官网文档按需加入
    beforeMount(app) {
      console.log('挂载前', app)
    },
    afterMount(app) {
      console.log('卸载后', app)
    },
  }
)

start({
  prefetch: false, //取消预加载
  sandbox: { experimentalStyleIsolation: true }, //沙盒模式
})

页面的话,主应用只添加了两个路由作为参考页,home和about,然后主应用配置就完成了:

const routes = [
  {
    path: '/',
    name: 'home',
    component: () => import('@/views/home.vue'),
  },
  {
    path: '/about',
    name: 'about',
    component: () => import('@/views/about.vue'),
  }
]

现在主应用配置基本完成,美化一下样式,代码:

<template>
  <div class="MainAppVue">
    <el-menu
      :default-active="activeIndex"
      class="el-menu-demo"
      mode="horizontal"
      background-color="#545c64"
      text-color="#fff"
      active-text-color="#ffd04b"
      @select="handleSelect"
    >
      <el-menu-item index="/">主应用Home</el-menu-item>
      <el-menu-item index="/about">主应用About</el-menu-item>
      <el-menu-item index="/subHomePage">子应用</el-menu-item>
    </el-menu>
    <router-view></router-view>
  </div>
  <!-- 子应用绑定容器 -->
  <div id="qiankun-subAppContainer"></div>
</template>
<script setup>
import { ref } from 'vue'
import { useRouter } from 'vue-router'
const router = useRouter()

const activeIndex = ref('/')
const handleSelect = (key, keyPath) => {
  router.push({ path: key })
}
</script>
<style>
body {
  margin: 0px;
}
</style>

效果如下:
在这里插入图片描述

创建子应用

和创建主应用的步骤一致,但是因为我们使用的是Vite构建,需要引用Vite插件来兼容qiankun环境:

npm install vite-plugin-qiankun -S

路由配置文件需要增加默认路由前缀,以下router.js完整代码:

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

const routes = [
  {
    path: '/',
    name: 'home',
    component: () => import('@/views/home.vue'),
  },
  {
    path: '/about',
    name: 'about',
    component: () => import('@/views/about.vue'),
  },
]

const router = createRouter({
  history: createWebHistory(qiankunWindow.__POWERED_BY_QIANKUN__ ? `/subHomePage` : '/'),   //这里需要配置/subHomePage,不然会点击跳转home到主应用的home
  routes,
})

export default router

子应用main.js需要兼容子应用单独运行,所以要增加是不是qiankun环境的判断,vite引入的插件就很好解决了这个问题,完整代码如下:

import { createApp, ref } 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({ container } = {}) {
  instance = createApp(App)
  instance.use(router)
  instance.mount(container ? container.querySelector('#subapp') : '#subapp')
}

// 如何独立运行微应用?
if (!qiankunWindow.__POWERED_BY_QIANKUN__) {
  console.log('并不是qiankun渲染')
  render()
}

renderWithQiankun({
  mount(props) {
    render(props)
  },
  bootstrap() {
    console.log('%c', 'color:green;', ' ChildOne bootstrap')
  },
  update() {
    console.log('%c', 'color:green;', ' ChildOne update')
  },
  unmount(props) {
    instance.unmount()
    instance = null
  },
})

子应用App.vue配置一下路由跳转条件以及引入ElementPlus美化一下页面,完整代码:

<template>
  <div class="SubAppVue">
    <el-menu
      style="width: 300px; height: calc(100vh - 60px)"
      :default-active="activeIndex"
      class="el-menu-demo"
      background-color="#545c64"
      text-color="#fff"
      active-text-color="#ffd04b"
      @select="handleSelect"
    >
      <el-menu-item index="/">子应用Home</el-menu-item>
      <el-menu-item index="/about">子应用About</el-menu-item>
    </el-menu>
    <router-view></router-view>
  </div>
</template>
<script setup>
import { ref } from 'vue'
import { useRouter } from 'vue-router'
const router = useRouter()

const activeIndex = ref('/')
const handleSelect = (key, keyPath) => {
  router.push({ path: key })
}
</script>
<style>
body {
  margin: 0px;
}
.SubAppVue{
  display: flex;
}
</style>

最后修改vite.config.js适配主应用配置的端口以及其他qiankun标识,完整代码:

import { fileURLToPath, URL } from 'node:url'
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import qiankun from 'vite-plugin-qiankun'

import AutoImport from 'unplugin-auto-import/vite'
import Components from 'unplugin-vue-components/vite'
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'

// https://vite.dev/config/
export default defineConfig({
  plugins: [vue(),
    qiankun('qiankun-subApp', {
      useDevMode: true,
    }),
    AutoImport({
      resolvers: [ElementPlusResolver()],
    }),
    Components({
      resolvers: [ElementPlusResolver()],
    }),
  ],
  server: {
    port: 5555,
    headers: {
      // 重点1: 允许跨域访问子应用页面
      'Access-Control-Allow-Origin': '*',
    },
  },
  resolve: {
    alias: {
      '@': fileURLToPath(new URL('./src', import.meta.url)),
    },
  },
})

这样就完成了基础的主子应用的创建了,如果出现问题,比如报错:
application ‘xxx‘ died in status LOADING_SOURCE_CODE: [qiankun] You need 这时候就需要检查主子应用是不是认定的子应用名称匹配以及检查子应用的Vite.config.js是不是有问题,接下来附上页面成品图:
在这里插入图片描述
到这里,基础的页面搭建就结束了,接下来我会继续完善文章,比如:

  • qiankun主子应用如何通过pinia进行通信
  • qiankun主子应用部署到服务器资源访问异常问题
  • qiankun主子应用如何配置动态路由

请持续关注,如果觉着对你有用,不妨动动发财小手点个赞👍,创作不易,如有引用,请务必标明出处。
欢迎各位评论区留言互相交流,谢谢!在这里插入图片描述

### 解决 qiankun前端框架中主应用和子应用路由模式不同 在 qiankun 构建的微前端架构下,当主应用与子应用采用不同的路由模式时(即主应用使用 `hash` 模式而某个子应用可能采用了 `history` 模式),确实会遇到一些兼容性和路径匹配方面的问题。为了确保两者能够和谐共存并正常工作,可以采取如下措施: #### 配置子应用以适应主应用的路由模式 对于基于 React 的子应用而言,在配置其内部使用的 `react-router-dom` 时,应当考虑调整路由器的基础路径以及模式设置。 如果主应用是以 `hash` 模式的 URL 来区分各个子应用,则建议所有子应用也统一到相同的 `hash` 模式之下。这可以通过修改子应用中的路由配置来达成。具体来说,就是在初始化 `BrowserRouter` 或者其他类型的 Router 组件时指定 `basename` 参数[^2]。 ```jsx import { BrowserRouter as Router } from 'react-router-dom'; <Router basename="/subapp"> {/* 子应用组件 */} </Router> ``` 这样做之后,即使是在 `hash` 模式下的父级页面环境中,子应用也能正确解析相对路径,并且不会干扰到全局的历史记录管理机制。 而对于那些已经选择了 `history` API 进行导航控制的应用程序,可以在启动前通过环境变量或者其他方式动态设定基础路径,从而使得这些应用程序能够在被嵌入到另一个更大的 Web 应用之中时仍然保持独立运作的能力[^3]。 另外值得注意的是,qiankun 自身提供了针对这种情况的支持——它允许开发者为每一个注册过的子模块定义特定的生命钩子函数,在其中执行必要的初始化逻辑,比如重写窗口历史状态或是监听地址栏变化事件等操作。因此,利用好这一特性也可以帮助更好地处理跨域间的链接转换问题[^1]。 最后,考虑到实际开发过程中可能会面临更多复杂场景,推荐始终遵循官方文档给出的最佳实践指南来进行相应适配,同时积极关注社区内关于此话题的技术讨论,以便及时获取最新的解决方案和技术支持。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值