Skip to content

qiankun笔记

主应用注册

js
import { registerMicroApps, start } from 'qiankun'

registerMicroApps([
  {
    name: 'qiankun-vue',
    entry: '//localhost:5178',
    container: '#micro-app-container',
    activeRule: '/vue',
  },
  {
    name: 'qiankun-react',
    entry: '//localhost:5179',
    container: '#micro-app-container',
    activeRule: '/react',
  },
])

start()

子应用生命周期(vue为例)

js
// src/main.js
import { createApp } from 'vue'
import { renderWithQiankun, qiankunWindow } from 'vite-plugin-qiankun/dist/helper'
import './style.css'
import App from './App.vue'

let app = null

function render(props = {}) {
    const { container } = props
    const mountRoot = container ? container.querySelector('#app') : '#app'

    app = createApp(App)
    app.mount(mountRoot)
}

renderWithQiankun({
    bootstrap() {
        console.log('子应用初始化')
    },
    mount(props) {
        console.log('子应用挂载', props)
        render(props)
    },
    unmount() {
        console.log('子应用卸载')
        app?.unmount()
        app = null
    },
})

if (!qiankunWindow.__POWERED_BY_QIANKUN__) {
    render()
}

vite中

js
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import qiankun from 'vite-plugin-qiankun'

// https://vite.dev/config/
export default defineConfig({
  plugins: [
    vue(),
    qiankun('qiankun-vue', { useDevMode: true }),
  ],
  server: {
    port: 5174,
    cors: true,
    origin: '//localhost:5174',
  },
})

常用api

registerMicroApps(apps, lifeCycles?)

参数 :apps - Array<RegistrableApp> - 必选,微应用的一些注册信息

lifeCycles - LifeCycles - 可选,全局的微应用生命周期钩子

类型 : RegistrableApp

  • name - string - 必选,微应用的名称,微应用之间必须确保唯一。

  • entry - string | { scripts?: string[]; styles?: string[]; html?: string } - 必选,微应用的入口。

配置为字符串时,表示微应用的访问地址,例如 https://qiankun.umijs.org/guide/。

配置为对象时,html 的值是微应用的 html 内容字符串,而不是微应用的访问地址。微应用的 publicPath 将会被设置为 /。

  • container - string | HTMLElement - 必选,微应用的容器节点的选择器或者 Element 实例。如container: '#root' 或 container: document.querySelector('#root')。

  • activeRule - string | (location: Location) => boolean | Array<string | (location: Location) => boolean - 必选,微应用的激活规则。

支持直接配置字符串或字符串数组,如 activeRule: '/app1' 或 activeRule: ['/app1', '/app2'],当配置为字符串时会直接跟 url 中的路径部分做前缀匹配,匹配成功表明当前应用会被激活。

支持配置一个 active function 函数或一组 active function。函数会传入当前 location 作为参数,函数返回 true 时表明当前微应用会被激活。如 location => location.pathname.startsWith('/app1')。

  • loader - (loading: boolean) => void - 可选,loading 状态发生变化时会调用的方法。

  • props - object - 可选,主应用需要传递给微应用的数据。

LifeCycles

ts
type Lifecycle = (app: RegistrableApp) => Promise<any>;
  • beforeLoad - Lifecycle | Array<Lifecycle> - 可选

  • beforeMount - Lifecycle | Array<Lifecycle> - 可选

  • afterMount - Lifecycle | Array<Lifecycle> - 可选

  • beforeUnmount - Lifecycle | Array<Lifecycle> - 可选

  • afterUnmount - Lifecycle | Array<Lifecycle> - 可选

start(opts?)

参数 :opts - Options 可选 类型 :Options

  • prefetch - boolean | 'all' | string[] | (( apps: RegistrableApp[] ) => { criticalAppNames: string[]; minorAppsName: string[] }) - 可选,是否开启预加载,默认为 true。

配置为 true 则会在第一个微应用 mount 完成后开始预加载其他微应用的静态资源

配置为 'all' 则主应用 start 后即开始预加载所有微应用静态资源

配置为 string[] 则会在第一个微应用 mounted 后开始加载数组内的微应用资源

配置为 function 则可完全自定义应用的资源加载时机 (首屏应用及次屏应用)

  • sandbox - boolean | { strictStyleIsolation?: boolean, experimentalStyleIsolation?: boolean } - 可选,是否开启沙箱,默认为 true。

  • singular - boolean | ((app: RegistrableApp<any>) => Promise<boolean>); - 可选,是否为单实例场景,单实例指的是同一时间只会渲染一个微应用。默认为 true。

  • fetch - Function - 可选,自定义的 fetch 方法。

  • getPublicPath - (entry: Entry) => string - 可选,参数是微应用的 entry 值。

  • getTemplate - (tpl: string) => string - 可选。

  • excludeAssetFilter - (assetUrl: string) => boolean - 可选,指定部分特殊的动态加载的微应用资源(css/js) 不被 qiankun 劫持处理。

参数:appLink - string - 必选

用法:设置主应用启动后默认进入的微应用。

示例

js
import { setDefaultMountApp } from 'qiankun';

setDefaultMountApp('/homeApp');

loadMicroApp(app, configuration?)

参数 :app - LoadableApp - 必选,微应用的基础信息

  • name - string - 必选,微应用的名称,微应用之间必须确保唯一。

  • entry - string | { scripts?: string[]; styles?: string[]; html?: string } - 必选,微应用的入口(详细说明同上)。

  • container - string | HTMLElement - 必选,微应用的容器节点的选择器或者 Element 实例。如container: '#root' 或 container: document.querySelector('#root')。

  • props - object - 可选,初始化时需要传递给微应用的数据。 configuration - Configuration - 可选,微应用的配置信息

  • sandbox - boolean | { strictStyleIsolation?: boolean, experimentalStyleIsolation?: boolean } - 可选,是否开启沙箱,默认为 true。

默认情况下沙箱可以确保单实例场景子应用之间的样式隔离,但是无法确保主应用跟子应用、或者多实例场景的子应用样式隔离。当配置为 { strictStyleIsolation: true } 时表示开启严格的样式隔离模式。这种模式下 qiankun 会为每个微应用的容器包裹上一个 shadow dom 节点,从而确保微应用的样式不会对全局造成影响。

基于 ShadowDOM 的严格样式隔离并不是一个可以无脑使用的方案,大部分情况下都需要接入应用做一些适配后才能正常在 ShadowDOM 中运行起来(比如 react 场景下需要解决这些 问题,使用者需要清楚开启了 strictStyleIsolation 意味着什么。后续 qiankun 会提供更多官方实践文档帮助用户能快速的将应用改造成可以运行在 ShadowDOM 环境的微应用。 除此以外,qiankun 还提供了一个实验性的样式隔离特性,当 experimentalStyleIsolation 被设置为 true 时,qiankun 会改写子应用所添加的样式为所有样式规则增加一个特殊的选择器规则来限定其影响范围,因此改写后的代码会表达类似为如下结构:

scss
// 假设应用名是 react16
.app-main {
  font-size: 14px;
}

div[data-qiankun-react16] .app-main {
    font-size: 14px;
}

注意事项: 目前 @keyframes, @font-face, @import, @page 等规则不会支持 (i.e. 不会被改写)

  • singular - boolean | ((app: RegistrableApp<any>) => Promise<boolean>); - 可选,是否为单实例场景,单实例指的是同一时间只会渲染一个微应用。默认为 false。

  • fetch - Function - 可选,自定义的 fetch 方法。

  • getPublicPath - (entry: Entry) => string - 可选,参数是微应用的 entry 值。

  • getTemplate - (tpl: string) => string - 可选

  • excludeAssetFilter - (assetUrl: string) => boolean - 可选,指定部分特殊的动态加载的微应用资源(css/js) 不被 qiankun 劫持处理

initGlobalState(state)

参数 :state - Record<string, any> - 必选

用法 :定义全局状态,并返回通信方法,建议在主应用使用,微应用通过 props 获取通信方法。

返回

MicroAppStateActions

onGlobalStateChange: (callback: OnGlobalStateChangeCallback, fireImmediately?: boolean) => void, 在当前应用监听全局状态,有变更触发 callback,fireImmediately = true 立即触发 callback

setGlobalState: (state: Record<string, any>) => boolean, 按一级属性设置全局状态,微应用中只能修改已存在的一级属性

offGlobalStateChange: () => boolean,移除当前应用的状态监听,微应用 umount 时会默认调用

主应用:

js
import { initGlobalState, MicroAppStateActions } from 'qiankun';

// 初始化 state
const actions: MicroAppStateActions = initGlobalState(state);

actions.onGlobalStateChange((state, prev) => {
// state: 变更后的状态; prev 变更前的状态
    console.log(state, prev);
});
actions.setGlobalState(state);
actions.offGlobalStateChange();

微应用:

js
// 从生命周期 mount 中获取通信方法,使用方式和 master 一致
export function mount(props) {
    props.onGlobalStateChange((state, prev) => {
    // state: 变更后的状态; prev 变更前的状态
    console.log(state, prev);
});

props.setGlobalState(state);
}