背景
主子应用前端工程同域名,不同nginx服务的微前端落地
主应用
main.js
注册子应用
registerMicroApps([{
name: 'sub',
entry: '/sub-asst',
container: '#sub', // 主视口ID
activeRule: '/sub', // 注意entry和activeRule不能一致
props: {
getToken: () => getToken(),
getRefreshToken: () => get('refresh_token'),
},
}],{
beforeLoad: [
async (loadApp) => {
window.console.log('before load', loadApp);
},
],
beforeMount: [
async (mountApp) => {
window.console.log('before mount', mountApp);
},
],
afterMount: [
async (mountApp) => {
window.console.log('after mount', mountApp, document.querySelector('#app'));
},
],
afterUnmount: [
async (unloadApp) => {
window.console.log('after unload', unloadApp);
},
],
})
app.vue 或者主视口所在组件文件
启动子应用
start({
excludeAssetFilter: (assetUrl) => {
const whiteList = [];
const whiteWords = ['baidu', 'map'];
if (whiteList.includes(assetUrl)) {
return true;
}
return whiteWords.some((w) => assetUrl.includes(w));
},
prefetch: true,
sandbox: true,
singular: true,
});
nginx配置
配置子系统静态资源代理和接口代理
location /sub-asst {
proxy_pass 子系统前端服务地址;
proxy_set_header Host $host:$server_port;
proxy_connect_timeout 30s;
proxy_read_timeout 30s;
proxy_send_timeout 30s;
proxy_http_version 1.1;
}
location /sub/api {
proxy_pass 子系统后端服务地址;
...
}
子应用
安装vite-plugin-qiankun
npm install vite-plugin-qiankun
vite.coonfig.js
import qiankun from 'vite-plugin-qiankun';
return {
plugins[
...other plugins,
qiankun('sub', {
useDevMode,
})],
base: mode.command === 'serve' ? './' : env.VITE_BUNDLE_PATH,
}
VITE_BUNDLE_PATH 配置为/sub-asst,与主应用注册时的entry保持一致
main.js
import { renderWithQiankun, qiankunWindow } from 'vite-plugin-qiankun/es/helper';
let app: any;
const render = (props: any) => {
app = createApp(App);
app.use(pinia) // pinia 存储
.use(router) // 路由
const { container } = props;
let c = container ? container.querySelector('#app') : '#app';
app.mount(c);
};
if (qiankunWindow.__POWERED_BY_QIANKUN__) {
window.__POWERED_BY_QIANKUN__ = qiankunWindow.__POWERED_BY_QIANKUN__;
renderWithQiankun({
mount(props: any) {
if (props) {
Session.set('token', props.getToken());
Session.set('refresh_token', props.getRefreshToken());
}
render(props);
},
bootstrap() {
console.log('bootstrap');
},
unmount(props: any) {
app.unmount();
app = null;
console.log(props, 'unmount');
},
update(props: any) {
console.log(props.token);
console.log(props, 'update');
},
});
} else {
render({});
}
代码里再根据 window.POWERED_BY_QIANKUN 标记位隐藏菜单栏和头部菜单
request.ts
const service: AxiosInstance = axios.create({
baseURL: '/sub/api', // 请求地址与activeRule保持一致,后续加api方便前端识别接口进行转发
timeout: 50000, // 全局超时时间
});
nginx配置
location / {
rewrite /sub-asst/(.*) /$1 break;
try_files $uri $uri/ /index.html;
}