基座与子应用:qiankun 接入实战

本节目标

qiankun 的核心是「基座注册子应用,子应用暴露生命周期」。基座用 registerMicroApps 声明「哪个路由挂哪个子应用、去哪加载它的入口 HTML」,再 start() 启动。

// 运行环境:基座是 Vue3 或 React 项目;先装 qiankun
// npm i qiankun
// src/micro.js(基座主文件)
import { registerMicroApps, start } from 'qiankun'

registerMicroApps([
  {
    name: 'orderApp',                 // 子应用唯一名
    entry: '//localhost:7100',        // 子应用跑起来的地址(开发期用端口)
    container: '#subapp',             // 基座里用于挂载子应用的 DOM 容器
    activeRule: '/order',             // 访问 /order* 时加载 orderApp
    props: { token: 'xxx', theme: 'dark' } // 传给子应用的初始化数据
  },
  {
    name: 'goodsApp',
    entry: '//localhost:7200',
    container: '#subapp',
    activeRule: '/goods'
  }
])

start() // 启动 qiankun,之后路由命中 activeRule 就自动挂载对应子应用

子应用这边,要做的只是「把入口改造成导出生命周期」,并把自己挂到 window.__POWERED_BY_QIANKUN__ 时由基座控制挂载:

// 运行环境:子应用(以 Vue3 为例);先装 qiankun(基座子应用都要 qiankun)
// src/micro-entry.js
import { createApp } from 'vue'
import App from './App.vue'

let app = null
function render(props = {}) {
  app = createApp(App)
  app.mount('#app') // 注意:容器 id 要和子应用自己 index.html 的挂载点一致
}

// 关键:导出三个生命周期钩子,基座在对应时机调用
export async function bootstrap() {
  console.log('[orderApp] bootstraped')
}
export async function mount(props) {
  console.log('[orderApp] props from 基座:', props.token) // 拿到基座传的 props
  render(props)
}
export async function unmount() {
  if (app) app.unmount() // 卸载时清掉 Vue 实例,避免内存泄漏/事件残留
}
// 独立运行时(直接 npm run dev 不被基座加载)也要能跑
if (!window.__POWERED_BY_QIANKUN__) {
  render()
}

子应用的 vue.config.js 还要配 webpack 的 publicPath 为 './',让基座能正确加载它的静态资源——这是 qiankun 接入最常见的坑之一。

名词解释

registerMicroApps:qiankun 基座的注册函数,传入「子应用清单」(名字、入口、容器、激活路由、props)。

生命周期钩子(bootstrap / mount / unmount):子应用必须导出的三个函数。基座在「首次加载 / 每次进入路由 / 离开路由」时分别调用,控制子应用的创建与销毁。

entry:子应用对外暴露的入口 HTML 地址(开发期通常是 localhost:端口,生产期是子应用自己部署的域名)。基座通过它拉取子应用的 JS/CSS。

props:基座在注册时通过 props 传给子应用的数据(如登录 token、主题),子应用在 mount(props) 里接收。

课后练习

练习 1:子应用为什么要判 window.__POWERED_BY_QIANKUN__?

答案:为了让子应用「既能被基座加载、也能自己单独 npm run dev 跑」。被基座加载时由基座调用 mount 来 render;独立运行时没有基座,就要自己直接 render()。这个判断就是区分这两种模式。

练习 2:container: '#subapp' 和子应用自己的挂载点冲突会怎样?

答案:qiankun 会把子应用挂载到基座的 #subapp 容器里;若子应用 render() 又 mount('#app') 且基座里没有 #app,会找不到节点挂载失败。约定上子应用挂载点 id 要存在,且不要和基座其它节点重名。

总结

qiankun 接入就三件事:基座 registerMicroApps + start、子应用导出 bootstrap/mount/unmount、子应用配 publicPath。props 是把基座数据喂给子应用的通道。最容易踩的坑是子应用 publicPath 没设 ./ 导致静态资源 404——记住「子应用对自己的资源要用相对路径」。下一节讲主子和路由怎么共存不打架。