前言

用 vue3 官方脚手架创建出来的工程是基于 vite的。vitewebpack 是有差别的,vite的开发时运用了浏览器支持原生的 es6 语法点的优势,但是这种优势对于接入 qiankun是有问题的。qiankun是使用 import-entry-html进行 html 的获取和解析,并通过 eval + with执行入口文件拿到生命周期,在执行时原生的 import A from 'A.js'语法会报错。
因此其实 vue3 接入 qiankun 的问题并不在 vue3 ,而在于 vite。
针对这个问题,开源社区有人开发了 vite-plugin-qiankun插件可以让 vite 工程接入 qiankun,这里就是使用该插件实现的接入。

安装插件并使用

  1. npm i vite-plugin-qiankun
  1. // vite.config.ts
  2. import { defineConfig } from 'vite'
  3. import qiankun from 'vite-plugin-qiankun';
  4. const useDevMode = true
  5. // https://vitejs.dev/config/
  6. export default defineConfig({
  7. plugins: [
  8. qiankun('vue3-app1', {
  9. useDevMode
  10. })
  11. ]
  12. })

导出生命周期

  1. import { renderWithQiankun, qiankunWindow } from 'vite-plugin-qiankun/dist/helper';
  2. let app: any = null
  3. function render(props: any) {
  4. const { container } = props;
  5. app = createApp(App)
  6. app.use(createPinia())
  7. app.use(router)
  8. app.mount(container ? container.querySelector('#app') : '#app');
  9. }
  10. renderWithQiankun({
  11. mount(props) {
  12. console.log('mount');
  13. render(props);
  14. },
  15. bootstrap() {
  16. console.log('bootstrap');
  17. },
  18. unmount(props: any) {
  19. console.log('unmount');
  20. app.unmount();
  21. app = null;
  22. },
  23. update() {
  24. }
  25. });
  26. if (!qiankunWindow.__POWERED_BY_QIANKUN__) {
  27. render({});
  28. }

设置路由 base

  1. import { createRouter, createWebHistory } from 'vue-router'
  2. import HomeView from '../views/HomeView.vue'
  3. import { qiankunWindow } from 'vite-plugin-qiankun/dist/helper';
  4. const router = createRouter({
  5. // 路由 base
  6. history: createWebHistory(qiankunWindow.__POWERED_BY_QIANKUN__ ? "/app1" : import.meta.env.BASE_URL),
  7. routes: [
  8. {
  9. path: '/',
  10. name: 'home',
  11. component: HomeView
  12. }
  13. ]
  14. })
  15. export default router

配置 vite

资源路径问题

qiankun 在加载子应用的资源的时候由于子应用资源是 /xx/x这样的路径,会自动拼接主应用的域名导致资源加载 404。qiankun 有提供一个运行时的变量 window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__,该值为加载的子应用的域名地址。修改打包工具的资源动态 base 即可。
但是 vite 没有提供动态配置 base 的功能。

  1. export default defineConfig({
  2. server: {
  3. origin: 'http://localhost:5173/', // 开发环境的资源完整域名前缀
  4. },
  5. base: "http://localhost:5173/" // 完整域名路径只在生产环境生效
  6. })

js / css 没有隔离的问题

vite-plugin-qiankun插件的原理是将入口文件改成了 import() 函数的方式。因此 js 的 eval + with建立沙箱失效,导致在开发环境 js 没有隔离,js 没有隔离导致 css 的 style 的 appendChild 拦截失效,css 隔离也失效。
但是生产环境下,js / css 隔离还是生效的。