Skip to content

改造子应用

新增 public.js 文件

javascript
if (window['__POWERED_BY_QIANKUN__']) {
    __webpack_public_path__ = window['__INJECTED_PUBLIC_PATH_BY_QIANKUN__']
}

改造 main.js

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

Vue.use(VueRouter)

let router = null;
let instance = null;
function render(props = {}) {
  const { container } = props;
  router = new VueRouter({
    mode: 'hash',
    base: window['__POWERED_BY_QIANKUN__'] ? '#/micro-app' : '#/', // hash 模式要带上 #
    routes,
  });
  instance = new Vue({
    router,
    store,
    render: (h) => h(App),
  }).$mount(container ? container.querySelector('#app') : '#app');
}
// 独立运行时
if (!window['__POWERED_BY_QIANKUN__']) {
  render();
}
// 这三个声明周期函数都要导出,且需要返回 promise
export async function bootstrap() {
  console.log('[vue] vue app bootstraped');
}
export async function mount(props) {
  console.log('micro-one-mount', props);
  render(props);
}
export async function unmount() {
  instance.$destroy();
  instance.$el.innerHTML = '';
  instance = null;
  router = null;
}

改造 vue.config.js

js
module.exports = {
  devServer: {
    headers: {
      'Access-Control-Allow-Origin': '*',
    },
    proxy: {
      "/app": {
        target: `http://192.168.32.108:2122`,
      }
    }
  },
  configureWebpack: {
    output: {
      /*
      *  qiankun 如何子应用入口的方式:
      *  1. 最后一个 script 标签
      *  2. 和子应用 name 匹配的包名
      *  3. 带有 entry 属性的 script 标签
      * */
      library: `导出的js包名`,
      // 把微应用打包成 umd 库格式
      libraryTarget: 'umd',
    },
  },
};

将子应用路由模式和主应用保持一致

官方文档似乎并没有规定主应用和子应用路由模式需要一致

但是为了后续其它问题的处理简单一点,这里将路由模式保持一致

由于每个子应用都有一个固定的 activeRule, 因此需要给对应的子应用加上这个前缀:

为所有路由增加前缀#/micro-app,与activeRule保持一致

javascript
// 注意 hash 模式时,base 要对应地带上 #
const prefix = '#/micro-app'
{
    mode: 'hash'
    base: window['__POWERED_BY_QIANKUN__'] ? prefix : '#/'
}

到此为止,主应用和子应用都改造完毕,可以运行了

注意事项

某些特定情况下,子应用导出的生命周期函数,主应用可能找不到,解决方案:

  • vue.config.js中的library值与name保持一致
  • 使用插件对打包后的main.jsscript标签添加entry属性

若使用到了axios,请使用最新版本

相关插件 HtmlWebpackInjectAttributesPlugin

javascript
new HtmlWebpackInjectAttributesPlugin({
    entry: tag => {
        if (tag.attributes.src) {
            return tag.attributes.src.includes('app')
        }
        return false
    }
})

其它配置见 官方文档

0