微前端框架 之 qiankun

qiankun文档: 快速上手

微前端 : 是最近一年国内前端领域被频繁提及的关键字,虽然它并不是一个全新的领域/技术,但很显然在当今越来越多的前端应用即将步入第 3 个、第 5 个甚至更久的年头的背景下,如何给 巨石应用/遗产应用 注入新鲜的技术血液已经成为我们不得不正视的问题,而微前端正是解决这类问题的一个非常合适的解决方案。

qiankun : 是一个生产可用的微前端框架,它基于 single-spa,具备 js 沙箱、样式隔离、HTML Loader、预加载 等微前端系统所需的能力。qiankun 可以用于任意 js 框架,微应用接入像嵌入一个 iframe 系统一样简单。

应用场景:  1. 主应用与多个相互独自的微应用 一起构成了整个大的微前端应用

                  2. 可以在同一个页面中,加载多个不同的微应用,每个微应用都是主应用的组成部分 或者是 提供一些增强能力,这种场景可以说是微应用粒度的前端组件化。

即: qiankun 相当于 route-based 的控制台应用,做为一个微应用的聚合框架而被使用。

 使用步骤:

1. 主应用安装

yarn add qiankun  # or npm i qiankun -S

2. 在主应用中注册微应用

import { registerMicroApps,runAfterFirstMounted, start } from 'qiankun';

// window.qiankunStarted 为严谨,防止加载多次 (可省略) 
if (!window.qiankunStarted) {
  window.qiankunStarted = true;
  registerMicroApps(
    [
      {
        name: 'invoice', // 子应用名的标识
        entry: `${process.env.VUE_APP_INVOICE_URL}`, // 子应用的目标地址, 可在环境变量中配置
        container: '#subapp-viewport', // 把加载到的子路由界面放在某个容器中
        // loader,
        activeRule: '/invoice', // 加载以/invoice开头的路由
      },

    ],
    // 主应用的生命周期
    // {
    //   beforeLoad: [
    //     app => {
    //       console.log('[LifeCycle] before load %c%s', 'color: green;', app.name);
    //     },
    //   ],
    //   beforeMount: [
    //     app => {
    //       console.log('[LifeCycle] before mount %c%s', 'color: green;', app.name);
    //     },
    //   ],
    //   afterUnmount: [
    //     app => {
    //       console.log('[LifeCycle] after unmount %c%s', 'color: green;', app.name);
    //     },
    //   ],
    // },
  );

  // 初始化主应用属性
  // const { onGlobalStateChange, setGlobalState } = initGlobalState({
  //   // user: 'qiankun',
  // });

  // onGlobalStateChange((value, prev) => console.log('[onGlobalStateChange - master]:', value, prev));

  // 设置自定义属性可传参到子应用中, 在子应用的mounted钩子中使用prop属性来接受
  // setGlobalState({
  //   // ignore: 'master',
  //   // user: {
  //   //   name: 'master',
  //   // },
  // });


  // setDefaultMountApp('/');


  start();

  // runAfterFirstMounted(() => {
  //   console.log('[MainApp] first app mounted');
  // });
}

 当微应用信息注册完之后,一旦浏览器的 url 发生变化,便会自动触发 qiankun 的匹配逻辑,所有 activeRule 规则匹配上的微应用就会被插入到指定的 container 中,同时依次调用微应用暴露出的生命周期钩子。

3. 配置渲染微应用容器的路由

 

 

3. 在微应用中导出相应的生命周期钩子

    3.1. 在微应用的 src 目录新增 public-path.js

if (window.__POWERED_BY_QIANKUN__) {
  // eslint-disable-next-line no-undef
  __webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__;
}

    3.2. 修改微应用中的路由文件router.js ,根据微应用标识限制路由范围

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

// 在微应用中的main.js中配置

let instance = null;
function render(props = {}) {
// props对象中的container属性指的是主应用的dom
  const { container } = props;
  instance = new Vue({
    router,
    store,
    render: (h) => h(App),
  }).$mount(container ? container.querySelector('#app') : document.querySelector('#app'));
}

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

/**
 * bootstrap 只会在微应用初始化的时候调用一次,下次微应用重新进入时会直接调用 mount 钩子,不会再重复触发 bootstrap。
 * 通常我们可以在这里做一些全局变量的初始化,比如不会在 unmount 阶段被销毁的应用级别的缓存等。
 */
export async function bootstrap() {
  console.log('[vue] vue app bootstraped');
}

// 应用每次进入都会调用 mount 方法,通常我们在这里触发应用的渲染方法
export async function mount(props) {
  console.log('[vue] props from main framework', props);
  render(props);
}
// unmount时销毁应用, 防止内存泄漏
export async function unmount() {
  instance.$destroy();
  instance.$el.innerHTML = '';
  instance = null;
}

4. 配置微应用的打包工具(vue.config.js

const { name } = require('./package');
module.exports = {
  devServer: {
    headers: {
      'Access-Control-Allow-Origin': '*',
    },
  },
  configureWebpack: {
    output: {
      library: `invoice`, // 应用标识, 和name保持一致
      libraryTarget: 'window', // 把微应用打包成window格式
      jsonpFunction: `webpackJsonp_${name}`,
    },
  },
};

使用qiankun微应用需要注意几点:

1. 在微应用src中新增 public-path.js 文件,用于修改运行时的 publicPath

2. 微应用建议使用 history 模式的路由,需要设置路由 base,值和它的 activeRule 是一样的。

3. 在入口文件最顶部引入 public-path.js,修改并导出三个生命周期函数。

4. 修改 webpack 打包。

主应用路由配置需要注意到的点:

1. 微应用入口路由需配置在主应用的后面. 否则主应用的界面显示不出来

 2. 如遇到路由显示的顺序问题, 如上图, 第一个路由菜单需显示在左侧导航栏的最后面, 可以给每个路由设置order属性, 用于在渲染导航栏菜单之前进行排序.

 

3. 如遇到样式冲突, 则各自加载各自的vue和elementUI

  • 0
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值