从0到部署 qiankun 微前端实战

一、什么是微前端(Micro Frontends)?

微前端 就像微服务在后端的作用 —— 把一个大前端应用,拆分成多个小的、独立的子应用模块,彼此解耦,各自开发、部署、运行。

通俗来说,就是多个前端项目共存于一个页面里,各自为政但又协同工作
举个例子:

  • 主应用:框架和壳子(导航、全局状态、登录)
  • 子应用:
    • 商品模块(由商品团队开发)
    • 订单模块(由订单团队开发)
    • 用户模块(由用户团队开发)

这些子应用可以分别上线,不影响主应用和其他子应用。

二、为什么选择 qiankun?

qiankun 是阿里开源的微前端框架,基于 single-spa 做了增强,拥有以下优势:

  1. 接入简单,几行代码接入主子应用
  2. 技术栈无关:Vue、React、Angular、jQuery 都能用
  3. 样式隔离、JS 沙箱、安全可控
  4. 支持 prefetch、生命周期管理、缓存等高级特性

三、核心原理简述(简单理解即可)

主应用和子应用通信机制:

qiankun 利用了浏览器的 iframe 思想,但并不是真的用 iframe。它是通过:

  1. 加载子应用 HTML(如 http://localhost:7001)
  2. 把子应用的 DOM 插入主应用
  3. 执行其 JS 脚本,让它跑起来
  4. 它还通过沙箱技术隔离变量,避免子应用污染主应用。

四、项目搭建结构(React 示例)

我们用两个 React 应用举例:

  1. main-app(主应用,端口 8000)
  2. react-sub-app(子应用,端口 8001)
    文件结构如下:
qiankun-demo/
├── main-app/
└── react-sub-app/

五、主应用 main-app 配置(React + qiankun)

1. 安装依赖

npx create-react-app main-app
cd main-app
npm install qiankun

2. 在 main-app/src/main.tsx 中注册子应用

import ReactDOM from 'react-dom/client';
import { registerMicroApps, start } from 'qiankun';
import App from './App';

registerMicroApps([
  {
    name: 'react-sub-app',
    entry: '//localhost:8001', // 子应用地址
    container: '#subapp-container', // 挂载点
    activeRule: '/subapp', // 激活规则,访问 /subapp 时加载
  },
]);

start(); // 启动 qiankun

const root = ReactDOM.createRoot(document.getElementById('root')!);
root.render(<App />);

3. 设置挂载容器 App.tsx

export default function App() {
  return (
    <div>
      <h1>Main App</h1>
      <div id="subapp-container" />
    </div>
  );
}

六、子应用 react-sub-app 配置

1. 安装依赖

npx create-react-app react-sub-app
cd react-sub-app

2. 暴露生命周期函数(关键)

在 src/index.tsx 中添加:

import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';

// 独立运行时
if (!window.__POWERED_BY_QIANKUN__) {
  const root = ReactDOM.createRoot(document.getElementById('root')!);
  root.render(<App />);
}

// qiankun 生命周期钩子
export async function bootstrap() {
  console.log('React sub app bootstraped');
}

export async function mount(props: any) {
  const root = ReactDOM.createRoot(document.getElementById('root')!);
  root.render(<App />);
}

export async function unmount() {
  const root = document.getElementById('root');
  if (root) root.innerHTML = '';
}

3. 设置 publicPath(不设置会找不到资源)

// config-overrides.js
module.exports = {
  webpack: (config) => {
    config.output.publicPath = window.__POWERED_BY_QIANKUN__ ? '/subapp/' : '/';
    return config;
  },
};

解释:

window.POWERED_BY_QIANKUN 是 qiankun 自动注入的全局变量。

当你只单独启动子应用时(比如访问 localhost:8001),是 独立运行模式,不会有 qiankun 这个变量,必须自己渲染应用。

如果是 qiankun 主应用加载子应用,它会注入这个变量,此时就不要自行渲染了,否则会渲染两次。

七、本地启动并测试

启动主应用

cd main-app
npm start

启动子应用

cd react-sub-app
npm start

访问 http://localhost:8000/subapp 即可看到子应用挂载成功。

八、部署到生产环境(Nginx 示例)

主应用 nginx 配置

server {
  listen 80;
  server_name yourdomain.com;

  location / {
    root /var/www/main-app;
    try_files $uri /index.html;
  }

  location /subapp/ {
    proxy_pass http://localhost:8001/;
  }
}

子应用 nginx 配置

server {
  listen 8001;
  server_name subapp.yourdomain.com;

  location / {
    root /var/www/react-sub-app;
    try_files $uri /index.html;
  }
}

九、常见问题与解决方案

问题解决方案
子应用样式覆盖主应用开启样式隔离(scopedCSS: true)
子应用资源加载失败设置正确 publicPath
子应用刷新 404后端设置 history 模式支持
子应用之间通信困难使用 qiankun 的 props 或自建 eventBus

Q1. qiankun 是如何做到多个子应用共存的?它和 iframe 有啥区别?

qiankun 利用了 HTMLEntry 技术(会加载子应用的 HTML,然后动态插入 DOM 并执行 JS),而非 iframe。

它用的是 single-spa 的注册机制 + 沙箱隔离(proxy + scope 样式隔离)。

iframe 是完全隔离的环境,而 qiankun 是在主页面里动态注入,性能更好、资源共享灵活,但需要手动处理冲突。

Q2:如果多个子应用使用了相同的依赖(如 React 版本不同),会有什么问题?怎么解决?

答:

可能出现冲突,比如 React18 和 React17 的 hooks 不兼容。

解决方案:

  1. 子应用配置 externals,不打包 React,让主应用统一提供(共享依赖)。

  2. 或者反过来让各子应用独立运行,采用 shadow DOM 或 scope css 保证隔离。

  3. qiankun 支持 shared 配置,也可以通过模块联邦(Webpack 5)来优化依赖共享。

Q3:如何在主应用和子应用之间传递登录态或全局状态?

qiankun 的 registerMicroApps 中可以传 props 给子应用。

registerMicroApps([
  {
    name: 'react-sub-app',
    entry: '//localhost:8001',
    container: '#subapp-container',
    activeRule: '/subapp',
    props: {
      token: 'xxxx', // 传递 token
      userInfo: { name: 'xxxx' },
    },
  },
]);

子应用通过 props 参数拿到:

export async function mount(props: any) {
  console.log(props.token); // 获取主应用传过来的 token
}

Q4:子应用加载成功但页面空白?

可能是因为没有设置正确的 publicPath,导致资源加载失败。

  1. 使用 window.POWERED_BY_QIANKUN 动态设置 publicPath。

  2. 或者设置 webpack 的 output.publicPath 为 ‘//localhost:8001/’。

Q5: 应用刷新时报 404 错误?

可能是子应用用了前端路由(如 React Router),刷新时 Nginx/服务端没有处理 /subapp/xxx 路由。

Nginx 配置中加上 try_files $uri /index.html,让任何路径都回到入口页。

location /subapp/ {
  root /your/dist/path;
  try_files $uri /index.html;
}

Q6:子应用样式污染主应用或互相干扰?

CSS 是全局的,多个应用样式可能互相覆盖。

解决方案:

  1. 启用 qiankun 的沙箱机制和 scopedCSS 配置。

  2. 或者子应用全部使用 CSS Modules / Tailwind / Shadow DOM。

start({
  sandbox: {
    strictStyleIsolation: true, // 开启样式隔离
  },
});

Q7:子应用中事件或 setInterval 没有被清除,切换回来出现问题?

在 unmount 生命周期中一定要清理定时器、解绑事件监听等

export async function unmount() {
  clearInterval(timer);
  window.removeEventListener('resize', onResize);
  ReactDOM.unmountComponentAtNode(document.getElementById('root')!);
}

Q8: 多个子应用注册后,页面变慢或加载冲突?

没有开启预加载、重复挂载、没有懒加载。

开启 prefetch:

start({
  prefetch: true, // 提前加载子应用资源
});

或者使用 loadMicroApp 动态加载需要的子应用,避免过度注册。

### 乾坤微前端框架与React结合使用教程 #### 创建React子应用 为了创建一个可以作为微前端使用的React子应用,推荐使用`create-react-app`来初始化项目环境[^1]。这一步骤简化了许多配置工作,使得开发者能够专注于业务逻辑的开发。 ```bash npx create-react-app my-microfrontend-app cd my-microfrontend-app npm start ``` #### 配置生命周期函数 为了让React应用成为qiankun兼容的应用程序,需要定义特定的生命週期钩子——`bootstrap`, `mount`, 和 `unmount`。这些方法允许主应用程序控制子应用的行为,在加载、渲染和卸载阶段执行必要的操作[^3]。 ```javascript import React from 'react'; import ReactDOM from 'react-dom/client'; import App from './App'; const render = (props) => { const container = document.getElementById('root'); const root = ReactDOM.createRoot(container); root.render(<App />); }; // 初始化时调用 export async function bootstrap() { console.log('React app bootstrapped'); } // 加载组件并将其挂接到DOM树上 export async function mount(props) { render(props); } // 卸载组件前清理资源 export async function unmount() { const container = document.getElementById('root'); const root = ReactDOM.createRoot(container); root.unmount(); } ``` #### 注册子应用至QianKun Shell Application 最后一步是在壳应用中注册这个新创建的React子应用。通过向shell application传递相应的参数完成这一过程,包括名称、入口URL和其他选项[^4]。 ```javascript import { registerMicroApps, start } from 'qiankun'; registerMicroApps([ { name: 'my-react-subapp', entry: '//localhost:3000', // 子应用的服务地址 container: '#subapp-container', activeRule: '/react' } ]); start(); // 启动qiankun ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值