微前端qiankun(vue3+vite5+vue-router4)开发配置中遇到的问题

759 阅读3分钟

技术栈:vue3+vite5+qiankun2+vue-router4

项目地址

1. 没有路由子应用: No match found for location with path "/child-web"

原因分析:主应用和子应用一些配置要一致

主应用

qiankun/app.js

image.png

views/childWebApp/index.vue

<template>
    <div id="child-web"></div>
</template>

<script setup name="childWebApp">

说明:

  • name:必须与子应用注册名字相同
  • entry: 入口路径,开发时为子应用所启本地服务,上线时为子应用线上路径,必须能够访问成功,如:'http://localhost:8090/pcache-web',
  • container:子应用挂载的节点,和views/childWebApp/index.vue中的id值保持一致
  • activeRule: 当访问路由为/micro-vue 时加载子应用

.env.development

VITE_EVN = 'development'

# base api

VITE_BASE_URL = '/config-web/'

# micor app
VITE_APP_CHILD = ':8080/child-web' 
VITE_APP_PCACHE = ':8090/pcache-web' 

子应用

vite.config.ts

image.png

.env.development


# 本地运行端口号
VITE_PORT = 8080
# 本地运行地址
VITE_PUBLIC_PATH = '/child-web'

2. Target container with #child-web not existed while child-web loading!

image.png

原因1:

qiankun 抛出这个错误是因为 渲染子应用的过程中,container容器丢失导致

解决1:

在主应用设置子应用文件夹下onMounted生命周期中添加start事件

<template>
    <div id="child-web"></div>
</template>

<script setup>
import { onMounted } from 'vue'
import { start } from 'qiankun'
onMounted(() => {
    if (!window.qiankunStarted) {
        window.qiankunStarted = true
        start({
            prefetch: true, // 是否开启预加载
            sandbox: {
                experimentalStyleIsolation: true, // 实验性的样式隔离
            },
        })
    }
})
</script>

当然,在mian.js中,也是有start方法的

import start from './qiankun/index'

start({
    sandbox: true,
    prefetch: true, //是否开启预加载
})

原因2:

主应用和子应用(微应用)中的base必须一致

解决2:

子应用(微应用)

VITE_PUBLIC_PATH = '/child-web'
import { type ConfigEnv, type UserConfigExport, defineConfig, loadEnv } from 'vite'
import * as path from 'path'
import vue from '@vitejs/plugin-vue'
import qiankun from 'vite-plugin-qiankun'

export default (configEnv: ConfigEnv): UserConfigExport => {
    const viteEnv = loadEnv(configEnv.mode, process.cwd())
    const { VITE_PUBLIC_PATH,VITE_QK_NAME } = viteEnv
    console.log(viteEnv)
    return {
        base: VITE_PUBLIC_PATH, //'/child-web'
        plugins: [
            vue(),
            qiankun(VITE_PUBLIC_PATH, { //'child-web'
                //子应用名字,与主应用注册的子应用名字保持一致
                useDevMode: true,
            }),
        ],
    }
}

主应用

  1. .env.developmentVITE_APP_CHILD = ':8080/child-web' image.png
  2. views/childWebApp/index.vue<div id="child-web"></div> image.png
  3. router/index.jspath: '/child-web', image.png
  4. qiankun/app.jsentry``activeRule image.png

但是在只是当个页面,没有路由加载时,手动刷新页面,页面也会抱错,Error: [qiankun]: Target container with #child-web not existed while child-web loading!

原因分析:页面还没加载完成,qiankun就已经加载完了,所有找不到container

解决:异步引入qiankun方法,这样container的onMounted生命周期中也不需要多写调用一次start方法

import { start } from 'qiankun'

//添加定时器,异步请求,确保微应用加载完成后再执行start方法
setTimeout(() => {
    start({
        sandbox: true,
        prefetch: true, //是否开启预加载
    })
}, 0)

3. globalState tools will be removed in 3.0, pls don't use it!

image.png

4.state has not changed!

image.png

5. TypeError: path.startsWith is not a function

image.png

6. main.ts:63 [Vue Router warn]: No match found for location with path "/pcache-web/login"

image.png

7. 路由子应用: No match found for location with path "/pcache-web/login"

image.png

原因分析:567的问题都是因为路径不对

解决:“路由子应用”中的所有路由path必须添加上VITE_PUBLIC_PATH = '/pcache-web'

(1) 静态路由

import { qiankunWindow } from 'vite-plugin-qiankun/dist/helper'
import { HOME_URL } from '@/routers/helper'
/**
 * staticRouter (静态路由) 接入qiankun是,需要添加上VITE_PUBLIC_PATH
 */
export const staticRouter: RouteRecordRaw[] = [
    {
        path: '/',
        redirect: HOME_URL,
    },
    {
        path: '/login',
        name: 'login',
        component: () => import('@/views/login/index.vue'),
        meta: {},
    },
    {
        path: '/layout',
        name: 'layout',
        component: () => import('@/layouts/index.vue'),
        redirect: HOME_URL,
        children: [],
    },
].map((item) => ({ ...item, path: qiankunWindow.__POWERED_BY_QIANKUN__ ? VITE_PUBLIC_PATH + item.path : item.path }))

(2) 动态路由(通过接口返回路由path动态添加)

image.png

(3) .evn中的全局路由

VITE_ROUTER_MODE = hash
VITE_HOME_URL = '/overview'
VITE_LOGIN_URL = '/login'
VITE_PUBLIC_PATH = '/pcache-web'

image.png

 router.replace(LOGIN_URL) //重定向到登陆页

(4) 开启路由模式:history模式或者hash模式

image.png

8. qiankun子应用图片加载失败

image.png

原因:路径不对

解决:设置子应用的公共基础路径

return {
        base: VITE_PUBLIC_PATH,
        server: {
            port: VITE_PORT, //端口号
            origin: 'http://localhost:' + VITE_PORT, //http://localhost:8090
            open: VITE_OPEN, //是否自动在浏览器打开
            host: true,
            hmr: true,
            watch: {
                usePolling: true, // 修复HMR热更新失效
            },
         
        },
}

image.png

相关链接