vue 项目作为子应用 接入 qiankun 框架 改造笔记

qiankun 官网:https://qiankun.umijs.org/zh/

vue 微应用官方文档:https://qiankun.umijs.org/zh/guide/tutorial#vue-%E5%BE%AE%E5%...

先看官方文档介绍的步骤:

1,添加并引入 public-path.js

官方代码如下:

if (window.__POWERED_BY_QIANKUN__) {
  __webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__;
}

qiankun 框架在加载微应用时,会给微应用注入一些全局变量,其中包含了 POWERED_BY_QIANKUNINJECTED_PUBLIC_PATH_BY_QIANKUN 这两个变量。

POWERED_BY_QIANKUN 是一个布尔值,用于判断当前应用是否是在 qiankun 框架下运行。
INJECTED_PUBLIC_PATH_BY_QIANKUN 是在运行时注入的当前微应用的静态资源路径。

通过判断 POWERED_BY_QIANKUN 变量的值,可以确定当前应用是否在 qiankun 框架下运行。如果是,则将 INJECTED_PUBLIC_PATH_BY_QIANKUN 的值赋给 __webpack_public_path__,这样在动态加载资源时,Webpack 就会使用正确的路径来加载模块。

这种动态设置 publicPath 的方式可以确保在微应用中动态加载的资源路径都是正确的,使得微应用能够正常运行在 qiankun 框架的环境中。

2,入口文件 main.js 修改,为了避免根 id #app 与其他的 DOM 冲突,需要限制查找范围

个人对这句话的理解是一个系统内会接入多个微应用,也就可能会有多个 #app 所以代码里就有了

container ? container.querySelector('#app') : '#app'

因为 container 是从基座(主应用)传过来的,具体原理不做分析,照着官网写就好了。
官网代码片段如下:

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

Vue.config.productionTip = false;

let router = null;
let instance = null;
function render(props = {}) {
  const { container } = props;
  router = new VueRouter({
    base: window.__POWERED_BY_QIANKUN__ ? '/app-vue/' : '/',
    mode: 'history',
    routes,
  });

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

// 独立运行时
if (!window.__POWERED_BY_QIANKUN__) {
  render();
}

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

其中 bootstrap,mount,unmount 就是生命周期钩子,在官方文档中介绍生命周期钩子使用react做的实例,在这里:https://qiankun.umijs.org/zh/guide/getting-started#1-%E5%AF%B...

3,打包配置修改(vue.config.js)

这里官方就只给了一个代码示例如下:

const { name } = require('./package');
module.exports = {
  devServer: {
    headers: {
      'Access-Control-Allow-Origin': '*',
    },
  },
  configureWebpack: {
    output: {
      library: `${name}-[name]`,
      libraryTarget: 'umd', // 把微应用打包成 umd 库格式
      jsonpFunction: `webpackJsonp_${name}`,
    },
  },
};

个人踩坑记录

首先,qiankun是一个相对成熟的框架了,用户量还是不错的,在遇到问题时,可以先翻阅一下官网的常见问题,或各大论坛。大概率会有前人遇到过相同的问题了、简单记录一下自己在改造过程中遇到的几个问题。

1,图标丢失

原因:wabpack打包出的文件在加载时会使用运行时publicPath:webpack_public_path,而字体图标不会
方法:vue.config.js 中添加如下代码

...
module.exports = {
...
  chainWebpack(config) {
    config.module
      .rule('fonts')
      .test(/.(ttf|otf|eot|woff|woff2)$/)
      .use('url-loader')
      .loader('url-loader')
      .tap((options) => {
        options = {
          // limit: 10000,
          name: '/static/fonts/[name].[ext]'
        }
        return options
      })
...
}
}

2,路由改造

接入主应用后,路由模式以及子应用的 base 都是需要改造的,在官网常见问题中有介绍。
因为我的项目需要同时接入两个qiankui系统,所以的的 base 也就有了以下代码:

if(window.__POWERED_BY_QIANKUN__){
  base=window.location.host=='XXX.XXX1.com'?`${process.env.VUE_ROUTER_BASE1}`:`${process.env.VUE_ROUTER_BASE2}`
}
const createRouter = () => new Router({
  scrollBehavior: () => ({ y: 0 }),
  base,
  mode:"history",
  routes: constantRoutes
})

3,axios 改造

应用嵌入qiankun后,发送请求应该往哪里发送?常规操作是改为发往主应用,由主应用做代理转发,否则会触发跨域请求。
所以创建 axios 时也需要判断运行环境

你可能感兴趣的:(qiankunvue.js)