一、qiankun 与微前端的核心概念
qiankun 是一个用于实现微前端架构的前端框架,它通过沙箱隔离和动态加载实现多应用共存的能力,从而让大型前端系统可以将业务拆分为若干独立的子应用。理解主应用与子应用之间的职责分离,是后续集成的前提。
在微前端场景中,主应用负责路由、全局状态、错误处理等统一能力,子应用则独立开发、打包和部署,拥有自己的路由和状态。qiankun 提供的 registerMicroApps、start 等 API,使得主应用能够按需加载和切换子应用,而无需改变子应用的代码结构。
核心能力还包括沙箱隔离、CSS 隔离和资源隔离,以避免不同子应用之间的样式冲突和全局变量污染。这对于在 Java 应用中嵌入前端微前端尤其关键,因为后端与前端通常需要在同一个域下协同工作。
二、在 Java 应用中搭建主应用(Host)
主应用的角色是承载 qiankun 的运行环境并提供微前端的入口,在实际场景中通常由一个前端构建产物与一个后端 Java 服务共同支撑。Spring Boot 常用来提供静态资源、路由转发和对后端接口的代理能力,从而实现统一部署。
为了实现跨域兼容与资源加载,常见做法包括在 Spring Boot 中暴露静态资源目录,并通过前端路由来控制子应用的激活。下面给出一个简化的 Java 配置与前端入口示例。
// Java: Web 配置示例(Spring Boot)
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;@Configuration
public class WebConfig implements WebMvcConfigurer {@Overridepublic void addResourceHandlers(ResourceHandlerRegistry registry) {// 将前端打包产物放在 classpath:/static/,如 /static/index.htmlregistry.addResourceHandler("/**").addResourceLocations("classpath:/static/");}@Overridepublic void addViewControllers(ViewControllerRegistry registry) {// 将根路径转发到 index.html,确保 qiankun 能正常加载registry.addRedirectViewController("/", "/index.html");}
}
嵌入在后端的控制器可实现简单的反向代理或接口聚合,以便前端微前端在同域下访问后端服务。在开发阶段,可以通过代理实现前后端分离的快速迭代。
三、将前端微应用以子应用接入 qiankun
在主应用中通过 qiankun 的 API 注册子应用,是实现微前端的关键步骤,子应用可以独立开发、构建并在运行时动态加载。以下示例展示了如何在主应用中注册两个子应用并启动 qiankun。
// 主应用(前端 JavaScript/TypeScript): 注册子应用
import { registerMicroApps, start } from 'qiankun';registerMicroApps([{name: 'app1',entry: '//localhost:7100', // 子应用入口地址container: '#micro-container', // 容器节点activeRule: '/app1' // 路由激活条件},{name: 'app2',entry: '//localhost:7200',container: '#micro-container',activeRule: '/app2'}
]);start({ prefetched: true }); // 启动 qiankun,prefetch 可提升加载体验
子应用通常独立开发、打包成静态资源,并通过懒加载在主应用中挂载,常见的子应用生命周期包括 bootstrap、mount、unmount。在子应用中实现这几个钩子,可以确保独立部署与热更新的顺利进行。
// 子应用(示意:app1 的 entry 为一个前端 SPA)
// app1/src/main.js
export async function bootstrap() {// 初始化子应用实例console.log('app1 bootstraped');
}
export async function mount(props) {// 使用 props 提供的全局上下文const { container } = props;const el = document.createElement('div');el.id = 'root-app1';el.innerHTML = '';container.appendChild(el);
}
export async function unmount(props) {// 清理资源const { container } = props;const el = container.querySelector('#root-app1');if (el) container.removeChild(el);
}
子应用的打包要设置正确的 publicPath,以确保资源能够在不同的宿主页面路径下正确加载。Webpack 的 output.publicPath 需要根据部署地址进行配置,从而避免资源加载失败。
四、前后端数据交互与路由整合
在微前端架构中,主应用承担全局状态与路由的统一管理,子应用通过 props 提供的上下文来获取需要的配置信息。全局状态的初始化与变更事件需要被子应用正确订阅,以确保跨应用的数据一致性。
跨子应用传递信息的典型做法是通过 props 传参和全局状态能力,如用户信息、权限标识等。下面示例展示了主应用注入全局状态的基本思路。
// 主应用:初始化全局状态
import { initGlobalState } from 'qiankun';const actions = initGlobalState({ user: null, token: '' });actions.onGlobalStateChange((state, prev) => {console.log('全局状态变化', state, prev);
});actions.setGlobalState({ user: { name: 'Alice' }, token: 'abc123' });
子应用在 mount 阶段通过 props 获得全局状态变更的回调与读取能力,从而保持与宿主的一致性。对于鉴权和会话管理,建议将 token 的获取与刷新策略统一在全局状态中处理。

// 子应用:在 mount 时读取初始全局状态
export async function mount(props) {const { getGlobalState, setGlobalState } = props;const state = getGlobalState();console.log('初始全局状态', state);// 根据需要对全局状态进行订阅或修改
}
五、部署与性能优化
部署层面,微前端通常将主应用和子应用分别打包成独立的静态资源,再通过同域或跨域的方式进行加载。静态资源的 CDN 与缓存策略对加载体验至关重要。
性能优化的关键点包括资源预取、按需加载和并行加载,以降低首次进入时的等待时间。通过 qiankun 的 prefetch 选项可提前加载部分子应用资源,提升首页响应速度。
<!-- 主应用的入口 HTML(简化示例) -->
<html>
<head><meta charset="UTF-8"><title>Host 应用</title>
</head>
<body><div id="micro-container"></div><script src="/static/js/qiankun.min.js"></script><script>// 注册子应用的示例代码</script>
</body>
</html>
// 通过代理后端接口获取初始化数据,减少前端重复请求的成本
async function initApp() {const res = await fetch('/api/init');const data = await res.json();// 将数据注入全局状态或子应用的初始化参数return data;
}
initApp().then(data => {console.log('初始化数据', data);
});
在部署阶段,确保跨域策略、证书、域名一致性,以及静态资源的版本化管理,以避免加载时的资源冲突和缓存穿透。监控指标如首屏时间、资源请求数和错误率是持续优化的重要依据。


