Appearance
qiankun 速查表
核心 API
主要函数
javascript
import {
registerMicroApps, // 注册微应用
start, // 启动 qiankun
loadMicroApp, // 动态加载微应用
initGlobalState // 初始化全局状态
} from 'qiankun';
基本用法
javascript
// 注册微应用
registerMicroApps([
{
name: 'app1',
entry: '//localhost:3001',
container: '#container',
activeRule: '/app1',
props: { data: 'from main' }
}
], {
// 生命周期钩子
beforeLoad: app => console.log('loading', app.name),
beforeMount: app => console.log('mounting', app.name),
afterMount: app => console.log('mounted', app.name),
beforeUnmount: app => console.log('unmounting', app.name),
afterUnmount: app => console.log('unmounted', app.name)
});
// 启动 qiankun
start({
prefetch: true, // 预加载
sandbox: {
strictStyleIsolation: true, // 严格样式隔离
experimentalStyleIsolation: false
}
});
微应用生命周期
完整生命周期
javascript
let app = null;
// 启动时调用一次
export async function bootstrap(props) {
console.log('应用启动', props);
}
// 每次进入时调用
export async function mount(props) {
console.log('应用挂载', props);
const { container } = props;
// 根据框架创建应用实例
app = new Vue({
router,
store,
render: h => h(App),
}).$mount(container ? container.querySelector('#app') : '#app');
}
// 每次切出/卸载时调用
export async function unmount(props) {
console.log('应用卸载', props);
if (app) {
app.$destroy();
app.$el.innerHTML = '';
app = null;
}
}
// 可选的更新钩子(使用 loadMicroApp 时)
export async function update(props) {
console.log('应用更新', props);
}
通信机制
全局状态通信
javascript
// 主应用 - 初始化全局状态
import { initGlobalState } from 'qiankun';
const { onGlobalStateChange, setGlobalState, getGlobalState } = initGlobalState({
user: { id: 1, name: 'admin' },
theme: 'dark'
});
// 监听全局状态变化
onGlobalStateChange((state, prev) => {
console.log('全局状态变化', state, prev);
}, true); // true 表示立即触发一次
// 微应用 - 使用全局状态
export async function mount(props) {
const { onGlobalStateChange, setGlobalState, getGlobalState } = props;
// 监听状态变化
onGlobalStateChange((state, prev) => {
console.log('微应用监听到状态变化', state, prev);
});
// 修改全局状态
setGlobalState({
user: { ...getGlobalState().user, lastVisit: Date.now() }
});
}
Props 通信
javascript
// 主应用传递数据
registerMicroApps([
{
name: 'app1',
entry: '//localhost:3001',
container: '#container',
activeRate: '/app1',
props: {
// 传递的数据
userInfo: { id: 1, name: 'John' },
theme: 'dark',
// 传递方法
onMainEvent: (data) => {
console.log('微应用触发主应用事件', data);
}
}
}
]);
// 微应用接收数据
export async function mount(props) {
const { userInfo, theme, onMainEvent } = props;
console.log('接收到的用户信息:', userInfo);
console.log('接收到的主题:', theme);
// 调用主应用方法
onMainEvent({ message: '来自微应用的消息' });
}
配置选项
start() 配置
javascript
start({
prefetch: true, // 启用预加载
// prefetch: ['app1'], // 预加载指定应用
// prefetch: false, // 禁用预加载
sandbox: {
// 沙箱配置
strictStyleIsolation: true, // 严格样式隔离
experimentalStyleIsolation: true, // 实验性样式隔离
type: 'legacy', // 沙箱类型: 'legacy' | 'proxy' | 'snapshot'
},
// 生命周期钩子
beforeLoad: app => console.log('加载前', app.name),
beforeMount: app => console.log('挂载前', app.name),
afterMount: app => console.log('挂载后', app.name),
beforeUnmount: app => console.log('卸载前', app.name),
afterUnmount: app => console.log('卸载后', app.name),
});
registerMicroApps 配置
javascript
registerMicroApps([
{
name: 'app1', // 应用名称
entry: '//localhost:3001', // 应用入口
container: '#container', // 挂载容器
activeRule: '/app1', // 激活规则
// activeRule: location => location.pathname.startsWith('/app1'),
props: { // 传递给微应用的属性
data: 'some data',
callback: () => console.log('callback')
}
}
], {
// 全局生命周期钩子
beforeLoad: app => {},
beforeMount: app => {},
afterMount: app => {},
beforeUnmount: app => {},
afterUnmount: app => {}
});
动态加载
loadMicroApp 使用
javascript
import { loadMicroApp } from 'qiankun';
// 动态加载微应用
const microApp = await loadMicroApp(
{
name: 'dynamic-app',
entry: '//localhost:3001',
container: '#dynamic-container',
},
{
sandbox: {
strictStyleIsolation: true,
},
props: {
data: 'from parent'
}
}
);
// 监听微应用状态
microApp.onGlobalStateChange((state) => {
console.log('微应用状态变化', state);
});
// 卸载微应用
await microApp.unmount();
构建配置
Webpack 配置
javascript
// webpack.config.js
module.exports = {
output: {
library: 'microApp', // 微应用名称
libraryTarget: 'umd', // 输出格式
jsonpFunction: `webpackJsonp_microApp`, // 避免冲突
publicPath: '//localhost:3001/' // 静态资源路径
},
devServer: {
headers: {
'Access-Control-Allow-Origin': '*' // 支持跨域
},
port: 3001
}
};
Vite 配置
javascript
// vite.config.js
import { defineConfig } from 'vite';
export default defineConfig({
build: {
rollupOptions: {
output: {
format: 'umd',
entryFileNames: '[name].js',
chunkFileNames: '[name].js',
assetFileNames: '[name].[ext]'
}
}
},
server: {
cors: true,
port: 3001
}
});
常用工具函数
工具函数
javascript
import { isMicroApp, getMicroAppState } from 'qiankun';
// 检查是否在微应用环境中
const isInMicroApp = window.__POWERED_BY_QIANKUN__;
// 检查微应用是否激活
if (isMicroApp()) {
console.log('当前在微应用环境中');
}
// 获取微应用状态
const appState = getMicroAppState();
// 创建路由适配器
function createMicroRouter(baseHistory, microRouter) {
if (window.__POWERED_BY_QIANKUN__) {
// 微前端环境下使用主应用的 history
return microRouter;
}
return microRouter;
}
常见问题解决
样式隔离问题
javascript
// 启用样式隔离
start({
sandbox: {
strictStyleIsolation: true, // 严格样式隔离
// 或
experimentalStyleIsolation: true // 实验性样式隔离
}
});
// CSS Modules 方式
// 在微应用中使用命名空间
.container[data-qiankun="app1"] {
.component {
color: blue;
}
}
路由冲突解决
javascript
// 微应用路由配置
export async function mount(props) {
const { container, routerBase = '/sub-app' } = props;
const router = new VueRouter({
mode: 'history',
base: routerBase, // 使用传递的基础路径
routes: [
{ path: '/', component: Home },
{ path: '/page', component: Page }
]
});
app = new Vue({ router }).$mount(container.querySelector('#app'));
}
跨域问题解决
javascript
// 微应用 webpack 配置
module.exports = {
devServer: {
headers: {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, PATCH, OPTIONS',
'Access-Control-Allow-Headers': 'X-Requested-With, content-type, Authorization'
}
}
};
性能优化
预加载策略
javascript
start({
prefetch: {
// 关键应用立即预加载
criticalAppList: [
{ name: 'critical-app', entry: '//localhost:3001' }
],
// 非关键应用空闲时预加载
idleAppList: [
{ name: 'idle-app', entry: '//localhost:3002' }
],
}
});
// 或使用函数自定义预加载逻辑
start({
prefetch: (apps) => {
// 自定义预加载逻辑
return apps.filter(app =>
app.status !== 'failed' &&
shouldPrefetch(app)
);
}
});
资源优化
javascript
// 微应用代码分割
// webpack.config.js
module.exports = {
optimization: {
splitChunks: {
chunks: 'all',
cacheGroups: {
vendor: {
test: /[\\/]node_modules[\\/]/,
name: 'vendors',
chunks: 'all'
}
}
}
}
};
调试技巧
开发环境调试
javascript
// 启用调试模式
if (process.env.NODE_ENV === 'development') {
window.__QIANKUN_DEVELOPMENT__ = true;
}
// 检查 qiankun 状态
console.log('qiankun loaded:', window.__POWERED_BY_QIANKUN__);
// 手动加载微应用(调试用)
const { loadMicroApp } = require('qiankun');
loadMicroApp({
name: 'test-app',
entry: '//localhost:3001',
container: '#container'
});
// 检查全局状态
const { initGlobalState } = require('qiankun');
const state = initGlobalState({});
console.log('global state:', state);
最佳实践
项目结构
main-app/ # 主应用
├── src/
│ ├── micro-apps/ # 微应用注册配置
│ ├── layouts/ # 布局组件
│ └── main.js
└── package.json
micro-apps/ # 微应用目录
├── user-center/ # 用户中心微应用
│ ├── src/
│ └── package.json
├── product-center/ # 产品中心微应用
└── order-center/ # 订单中心微应用
错误处理
javascript
// 主应用错误处理
window.addEventListener('error', (e) => {
console.error('Micro app error:', e);
});
window.addEventListener('unhandledrejection', (e) => {
console.error('Unhandled promise rejection:', e);
});
// 微应用错误处理
export async function mount(props) {
try {
// 应用初始化逻辑
} catch (error) {
console.error('Micro app mount failed:', error);
// 通知主应用错误
if (props.onError) {
props.onError(error);
}
}
}
常用代码片段
Vue 微应用模板
javascript
import { createApp } from 'vue';
import App from './App.vue';
import router from './router';
import store from './store';
let app = null;
export async function bootstrap(props) {
console.log('Vue app bootstrap', props);
}
export async function mount(props) {
console.log('Vue app mount', props);
const { container } = props;
app = createApp(App);
app.use(router);
app.use(store);
app.mount(container ? container.querySelector('#app') : '#app');
}
export async function unmount(props) {
console.log('Vue app unmount', props);
if (app) {
app.unmount();
app = null;
}
}
// 独立运行支持
if (!window.__POWERED_BY_QIANKUN__) {
createApp(App).use(router).use(store).mount('#app');
}
React 微应用模板
javascript
import React from 'react';
import ReactDOM from 'react-dom';
import { BrowserRouter } from 'react-router-dom';
import App from './App';
let app = null;
export async function bootstrap(props) {
console.log('React app bootstrap', props);
}
export async function mount(props) {
console.log('React app mount', props);
const { container } = props;
app = (
<BrowserRouter>
<App />
</BrowserRouter>
);
ReactDOM.render(
app,
container ? container.querySelector('#root') : document.getElementById('root')
);
}
export async function unmount(props) {
console.log('React app unmount', props);
if (app) {
ReactDOM.unmountComponentAtNode(
props.container ? props.container.querySelector('#root') : document.getElementById('root')
);
app = null;
}
}
// 独立运行支持
if (!window.__POWERED_BY_QIANKUN__) {
ReactDOM.render(<App />, document.getElementById('root'));
}
这份速查表涵盖了 qiankun 的核心概念、API 使用、配置选项、常见问题解决和最佳实践,可作为快速参考指南使用。