前言
用 vue3 官方脚手架创建出来的工程是基于 vite的。vite和webpack 是有差别的,vite的开发时运用了浏览器支持原生的 es6 语法点的优势,但是这种优势对于接入 qiankun是有问题的。qiankun是使用 import-entry-html进行 html 的获取和解析,并通过 eval + with执行入口文件拿到生命周期,在执行时原生的 import A from 'A.js'语法会报错。
因此其实 vue3 接入 qiankun 的问题并不在 vue3 ,而在于 vite。
针对这个问题,开源社区有人开发了 vite-plugin-qiankun插件可以让 vite 工程接入 qiankun,这里就是使用该插件实现的接入。
安装插件并使用
npm i vite-plugin-qiankun
// vite.config.tsimport { defineConfig } from 'vite'import qiankun from 'vite-plugin-qiankun';const useDevMode = true// https://vitejs.dev/config/export default defineConfig({plugins: [qiankun('vue3-app1', {useDevMode})]})
导出生命周期
import { renderWithQiankun, qiankunWindow } from 'vite-plugin-qiankun/dist/helper';let app: any = nullfunction render(props: any) {const { container } = props;app = createApp(App)app.use(createPinia())app.use(router)app.mount(container ? container.querySelector('#app') : '#app');}renderWithQiankun({mount(props) {console.log('mount');render(props);},bootstrap() {console.log('bootstrap');},unmount(props: any) {console.log('unmount');app.unmount();app = null;},update() {}});if (!qiankunWindow.__POWERED_BY_QIANKUN__) {render({});}
设置路由 base
import { createRouter, createWebHistory } from 'vue-router'import HomeView from '../views/HomeView.vue'import { qiankunWindow } from 'vite-plugin-qiankun/dist/helper';const router = createRouter({// 路由 basehistory: createWebHistory(qiankunWindow.__POWERED_BY_QIANKUN__ ? "/app1" : import.meta.env.BASE_URL),routes: [{path: '/',name: 'home',component: HomeView}]})export default router
配置 vite
资源路径问题
qiankun 在加载子应用的资源的时候由于子应用资源是 /xx/x这样的路径,会自动拼接主应用的域名导致资源加载 404。qiankun 有提供一个运行时的变量 window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__,该值为加载的子应用的域名地址。修改打包工具的资源动态 base 即可。
但是 vite 没有提供动态配置 base 的功能。
export default defineConfig({server: {origin: 'http://localhost:5173/', // 开发环境的资源完整域名前缀},base: "http://localhost:5173/" // 完整域名路径只在生产环境生效})
js / css 没有隔离的问题
vite-plugin-qiankun插件的原理是将入口文件改成了 import() 函数的方式。因此 js 的 eval + with建立沙箱失效,导致在开发环境 js 没有隔离,js 没有隔离导致 css 的 style 的 appendChild 拦截失效,css 隔离也失效。
但是生产环境下,js / css 隔离还是生效的。
