qiankun 微前端完全入门指南 - 从零到精通

一篇文章搞懂 qiankun:是什么、为什么、怎么用、什么时候用

📚 目录

  • 一、什么是微前端
  • [二、什么是 qiankun](#二、什么是 qiankun "#%E4%BA%8C%E4%BB%80%E4%B9%88%E6%98%AF-qiankun")
  • [三、为什么要用 qiankun](#三、为什么要用 qiankun "#%E4%B8%89%E4%B8%BA%E4%BB%80%E4%B9%88%E8%A6%81%E7%94%A8-qiankun")
  • [四、qiankun 核心概念](#四、qiankun 核心概念 "#%E5%9B%9Bqiankun-%E6%A0%B8%E5%BF%83%E6%A6%82%E5%BF%B5")
  • [五、快速上手:10 分钟搭建第一个微前端应用](#五、快速上手:10 分钟搭建第一个微前端应用 "#%E4%BA%94%E5%BF%AB%E9%80%9F%E4%B8%8A%E6%89%8B10-%E5%88%86%E9%92%9F%E6%90%AD%E5%BB%BA%E7%AC%AC%E4%B8%80%E4%B8%AA%E5%BE%AE%E5%89%8D%E7%AB%AF%E5%BA%94%E7%94%A8")
  • 六、技术栈兼容性
  • 七、进阶知识
  • [八、什么时候该用 qiankun](#八、什么时候该用 qiankun "#%E5%85%AB%E4%BB%80%E4%B9%88%E6%97%B6%E5%80%99%E8%AF%A5%E7%94%A8-qiankun")
  • 九、常见问题和解决方案
  • 十、学习路线图

一、什么是微前端

🤔 先从问题说起

想象你在开发一个大型电商网站:

  • 首页(营销团队负责)
  • 商品页(商品团队负责)
  • 购物车(订单团队负责)
  • 用户中心(用户团队负责)

传统做法:所有代码在一个项目里

perl 复制代码
my-ecommerce/
├── src/
│   ├── pages/
│   │   ├── home/          # 首页(营销团队)
│   │   ├── product/       # 商品页(商品团队)
│   │   ├── cart/          # 购物车(订单团队)
│   │   └── user/          # 用户中心(用户团队)
│   └── ...
└── package.json

会遇到的问题

  1. 协作困难 😫

    • 4 个团队改同一个代码仓库
    • Git 冲突不断
    • 一个人改的代码可能影响到别人
  2. 部署困难 😰

    • 营销团队想更新首页,必须重新部署整个应用
    • 其他团队的代码也被迫重新部署
    • 一旦有 bug,整个网站都挂了
  3. 技术栈固化 😓

    • 整个项目都得用 React,想用 Vue 不行
    • 想升级 React 版本,所有代码都得测一遍
  4. 编译越来越慢 🐌

    • 代码越来越多,打包要 10 分钟
    • 改一行代码,等 10 分钟才能看到效果

💡 微前端的解决方案

把一个大应用拆分成多个小应用,每个小应用独立运行

复制代码
主应用(基座)
├── 首页子应用(独立项目)
├── 商品子应用(独立项目)
├── 购物车子应用(独立项目)
└── 用户中心子应用(独立项目)

就像:

  • 传统应用:一个巨大的 Word 文档,所有内容都在里面
  • 微前端:一个文件夹,里面有多个独立的 Word 文档,需要时打开相应的文档

🎯 微前端的核心思想

"将前端应用拆解为一些更小、更简单的能够独立开发、测试、部署的小应用,然后再由主应用来加载这些小应用"

二、什么是 qiankun

🏛️ qiankun 简介

qiankun(乾坤) 是阿里巴巴开源的微前端框架,基于 single-spa 封装。

🎭 形象比喻

把 qiankun 想象成一个智能剧院

css 复制代码
┌─────────────────────────────────────────┐
│          qiankun 剧院(主应用)           │
│  ┌────────────────────────────────┐    │
│  │      舞台(容器 div)            │    │
│  │  ┌──────────────────────┐      │    │
│  │  │  正在表演的剧目        │      │    │
│  │  │  (当前激活的子应用)   │      │    │
│  │  └──────────────────────┘      │    │
│  └────────────────────────────────┘    │
│                                         │
│  剧目清单:                              │
│  ☐ 话剧(React 应用)                    │
│  ☑ 歌剧(Vue 应用) ← 正在播放           │
│  ☐ 舞剧(Angular 应用)                  │
│  ☐ 杂技(原生 JS 应用)                  │
└─────────────────────────────────────────┘
  • 主应用 = 剧院本身(提供舞台、灯光、座位)
  • 子应用 = 不同的演出剧目(独立制作、独立演出)
  • qiankun = 剧院的管理系统(决定什么时候演什么剧)

🔧 qiankun 的核心能力

  1. 应用加载 - 能加载各种前端应用
  2. 应用隔离 - 保证应用之间不互相干扰
  3. 应用通信 - 让应用之间能交流
  4. 生命周期管理 - 控制应用的启动、运行、卸载

三、为什么要用 qiankun

✅ 解决的核心问题

1. 团队协作问题

没有 qiankun 之前

css 复制代码
团队 A: "我要改首页"
团队 B: "我也要改首页相关的代码"
结果:Git 冲突,互相等待,效率低下

有了 qiankun 之后

yaml 复制代码
团队 A: 改自己的子应用项目
团队 B: 改自己的子应用项目
结果:互不干扰,并行开发

2. 部署问题

没有 qiankun 之前

复制代码
营销团队:我只改了首页一个按钮颜色
结果:整个应用重新部署,所有用户重新下载 10MB 的 JS

有了 qiankun 之后

复制代码
营销团队:只部署首页子应用
结果:只有访问首页的用户重新下载 1MB 的 JS,其他页面不受影响

3. 技术栈问题

没有 qiankun 之前

复制代码
老项目用 Vue 2 写的,想用 React 写新功能?
答:不行,全部重构吧

有了 qiankun 之后

复制代码
老项目用 Vue 2(作为子应用)
新功能用 React(另一个子应用)
答:可以!它们可以共存

4. 代码体积问题

没有 qiankun 之前

diff 复制代码
用户访问首页,加载了:
- 首页代码(1MB)
- 商品页代码(2MB)
- 购物车代码(1MB)
- 用户中心代码(1MB)
总计:5MB

用户:我只想看首页啊!为什么要下载这么多?

有了 qiankun 之后

diff 复制代码
用户访问首页,只加载:
- 主应用框架(200KB)
- 首页子应用(1MB)
总计:1.2MB

用户访问商品页时,才加载商品页子应用

📊 对比表格

维度 单体应用 qiankun 微前端
团队协作 多人改一个项目,冲突多 每个团队独立项目,无冲突
部署效率 改一处,全部署 改哪个部署哪个
技术栈 必须统一 可以不同
加载速度 一次加载所有代码 按需加载
风险控制 一处 bug 全挂 子应用 bug 不影响其他
学习成本 中等
架构复杂度 中高

四、qiankun 核心概念

🏗️ 架构图

css 复制代码
┌────────────────────────────────────────────────┐
│              浏览器窗口                          │
│  ┌──────────────────────────────────────────┐ │
│  │          主应用(Main App)               │ │
│  │  ┌────────────────────────────────────┐  │ │
│  │  │  导航栏 Header                      │  │ │
│  │  ├─────────┬──────────────────────────┤  │ │
│  │  │ 侧边栏   │   <div id="container">   │  │ │
│  │  │ Sidebar │   子应用挂载容器          │  │ │
│  │  │         │   ┌──────────────────┐   │  │ │
│  │  │ - 首页  │   │                  │   │  │ │
│  │  │ - 商品  │   │   当前激活的      │   │  │ │
│  │  │ - 购物车│   │   子应用内容      │   │  │ │
│  │  │ - 用户  │   │                  │   │  │ │
│  │  │         │   └──────────────────┘   │  │ │
│  │  └─────────┴──────────────────────────┘  │ │
│  │  Footer 底部栏                           │ │
│  └──────────────────────────────────────────┘ │
└────────────────────────────────────────────────┘

🎯 核心概念

1. 主应用(Main App / 基座)

职责

  • 提供页面框架(Header、Sidebar、Footer)
  • 注册所有子应用
  • 监听路由变化
  • 加载和卸载子应用

特点

  • 通常代码量很少
  • 不包含具体业务逻辑
  • 就像一个空房子,提供水电和框架

2. 子应用(Micro App)

职责

  • 实现具体的业务功能
  • 导出生命周期函数
  • 可以独立运行(独立访问)

特点

  • 是完整的前端应用
  • 有自己的路由、状态管理
  • 像房子里的租客,有独立的生活

3. 容器(Container)

就是一个普通的 div:

html 复制代码
<div id="container"></div>

子应用会被渲染到这个 div 里

4. 激活规则(activeRule)

决定什么时候显示哪个子应用:

javascript 复制代码
{
  name: 'app-home',
  activeRule: '/home',  // 当 URL 是 /home 时,激活这个应用
}

就像:

bash 复制代码
用户访问 www.example.com/home  → 显示首页子应用
用户访问 www.example.com/product → 显示商品子应用

五、快速上手:10 分钟搭建第一个微前端应用

🎬 实战教程

我们来做一个简单的例子:主应用 + 2 个 React 子应用

第一步:创建主应用

bash 复制代码
# 创建主应用目录
mkdir qiankun-demo
cd qiankun-demo
mkdir main-app
cd main-app

# 初始化项目
npm init -y
npm install qiankun react react-dom
npm install webpack webpack-cli webpack-dev-server html-webpack-plugin babel-loader @babel/core @babel/preset-react -D

创建 main-app/index.html

html 复制代码
<!DOCTYPE html>
<html>
<head>
  <title>qiankun 主应用</title>
  <style>
    body { margin: 0; font-family: Arial; }
    .header { background: #1890ff; color: white; padding: 20px; }
    .nav { background: #f0f0f0; padding: 10px; }
    .nav a { margin-right: 20px; color: #1890ff; text-decoration: none; }
    #container { padding: 20px; }
  </style>
</head>
<body>
  <div class="header">
    <h1>🎯 qiankun 微前端示例</h1>
  </div>
  <div class="nav">
    <a href="#/home">首页</a>
    <a href="#/app1">应用1</a>
    <a href="#/app2">应用2</a>
  </div>
  <div id="container">主应用加载中...</div>
  <script src="./index.js"></script>
</body>
</html>

创建 main-app/index.js

javascript 复制代码
import { registerMicroApps, start } from 'qiankun';

// 注册子应用
registerMicroApps([
  {
    name: 'app1',                           // 应用名称
    entry: '//localhost:3001',              // 应用地址
    container: '#container',                // 挂载容器
    activeRule: '#/app1',                   // 激活规则
  },
  {
    name: 'app2',
    entry: '//localhost:3002',
    container: '#container',
    activeRule: '#/app2',
  },
]);

// 启动 qiankun
start({
  prefetch: true,  // 预加载
  sandbox: true,   // 开启沙箱
});

console.log('✅ qiankun 主应用启动成功!');

创建 main-app/webpack.config.js

javascript 复制代码
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
  entry: './index.js',
  mode: 'development',
  devServer: {
    port: 3000,
    hot: true,
  },
  module: {
    rules: [
      {
        test: /\.jsx?$/,
        use: 'babel-loader',
        exclude: /node_modules/,
      },
    ],
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: './index.html',
    }),
  ],
};

第二步:创建子应用 1

bash 复制代码
# 回到根目录
cd ..
npx create-react-app app1
cd app1
npm install react-app-rewired -D

修改 app1/src/index.js

javascript 复制代码
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';

// 导出生命周期函数(qiankun 需要)
export async function bootstrap() {
  console.log('✅ App1 启动');
}

export async function mount(props) {
  console.log('✅ App1 挂载', props);
  ReactDOM.render(<App />, props.container ? props.container.querySelector('#root') : document.getElementById('root'));
}

export async function unmount(props) {
  console.log('✅ App1 卸载');
  ReactDOM.unmountComponentAtNode(props.container ? props.container.querySelector('#root') : document.getElementById('root'));
}

// 独立运行时(不在 qiankun 中)
if (!window.__POWERED_BY_QIANKUN__) {
  mount({});
}

修改 app1/src/App.js

javascript 复制代码
import React from 'react';

function App() {
  return (
    <div style={{ padding: 20, background: '#e6f7ff', borderRadius: 8 }}>
      <h2>🎨 这是子应用 1</h2>
      <p>我是用 React 开发的独立应用</p>
      <button onClick={() => alert('Hello from App1!')}>点击我</button>
    </div>
  );
}

export default App;

修改 app1/package.json 的 scripts

json 复制代码
"scripts": {
  "start": "react-app-rewired start",
  "build": "react-app-rewired build"
}

创建 app1/config-overrides.js

javascript 复制代码
module.exports = {
  webpack: (config) => {
    config.output.library = 'app1';
    config.output.libraryTarget = 'umd';
    config.output.publicPath = 'http://localhost:3001/';
    return config;
  },
  devServer: (configFunction) => {
    return (proxy, allowedHost) => {
      const config = configFunction(proxy, allowedHost);
      config.port = 3001;
      config.headers = {
        'Access-Control-Allow-Origin': '*',
      };
      return config;
    };
  },
};

第三步:创建子应用 2(同理)

bash 复制代码
cd ..
npx create-react-app app2
# 按照 app1 的方式配置,只需要把端口改成 3002,名称改成 app2

第四步:启动所有应用

bash 复制代码
# 终端 1:启动主应用
cd main-app
npm start  # 访问 http://localhost:3000

# 终端 2:启动子应用 1
cd app1
npm start  # http://localhost:3001

# 终端 3:启动子应用 2
cd app2
npm start  # http://localhost:3002

🎉 完成!

现在访问 http://localhost:3000,点击导航栏的链接,可以看到:

  • 点击"应用1",加载并显示子应用 1
  • 点击"应用2",加载并显示子应用 2
  • Header 和导航栏始终存在(主应用提供)
  • 只有中间的内容在切换(子应用)

🔍 关键代码解析

1. 主应用的核心代码

javascript 复制代码
import { registerMicroApps, start } from 'qiankun';

// 第一步:注册子应用
registerMicroApps([
  {
    name: 'app1',              // 唯一标识
    entry: '//localhost:3001', // 子应用地址
    container: '#container',   // 挂载到哪个 DOM
    activeRule: '#/app1',      // URL 匹配规则
  },
]);

// 第二步:启动
start();

就这么简单!主应用的核心就是这几行代码。

2. 子应用的核心代码

javascript 复制代码
// 导出三个生命周期函数
export async function bootstrap() {
  // 应用首次加载时调用,只会调用一次
}

export async function mount(props) {
  // 应用挂载时调用,每次激活都会调用
  ReactDOM.render(<App />, props.container);
}

export async function unmount(props) {
  // 应用卸载时调用
  ReactDOM.unmountComponentAtNode(props.container);
}

子应用需要做的就是:导出这三个生命周期函数

3. webpack 配置关键点

javascript 复制代码
config.output.library = 'app1';           // 暴露为全局变量
config.output.libraryTarget = 'umd';      // 使用 UMD 格式
config.output.publicPath = 'http://localhost:3001/'; // 资源路径

这样配置后,qiankun 才能正确加载子应用的代码。

六、技术栈兼容性

🎨 qiankun 支持的框架

qiankun 是技术栈无关的,几乎支持所有前端框架!

框架 支持情况 难度 官方示例
React ✅ 完美支持 ⭐ 简单
Vue 2/3 ✅ 完美支持 ⭐ 简单
Angular ✅ 完美支持 ⭐⭐ 中等
原生 JS ✅ 完美支持 ⭐ 简单
jQuery ✅ 完美支持 ⭐ 简单 可用
Svelte ✅ 支持 ⭐⭐ 中等 社区有
Next.js ⚠️ 部分支持 ⭐⭐⭐ 困难 需要特殊配置
Nuxt.js ⚠️ 部分支持 ⭐⭐⭐ 困难 需要特殊配置

💡 混合使用示例

你可以这样组合:

javascript 复制代码
registerMicroApps([
  {
    name: 'react-app',      // React 应用
    entry: '//localhost:3001',
    activeRule: '/react',
  },
  {
    name: 'vue-app',        // Vue 应用
    entry: '//localhost:3002',
    activeRule: '/vue',
  },
  {
    name: 'angular-app',    // Angular 应用
    entry: '//localhost:3003',
    activeRule: '/angular',
  },
  {
    name: 'jquery-app',     // jQuery 应用
    entry: '//localhost:3004',
    activeRule: '/jquery',
  },
]);

🌐 不同框架的接入方式

React 接入

javascript 复制代码
// index.js
export async function mount(props) {
  ReactDOM.render(<App />, props.container.querySelector('#root'));
}

Vue 2 接入

javascript 复制代码
// main.js
export async function mount(props) {
  new Vue({
    render: h => h(App),
  }).$mount(props.container.querySelector('#app'));
}

Vue 3 接入

javascript 复制代码
// main.js
export async function mount(props) {
  const app = createApp(App);
  app.mount(props.container.querySelector('#app'));
}

Angular 接入

typescript 复制代码
// main.ts
export async function mount(props) {
  platformBrowserDynamic()
    .bootstrapModule(AppModule)
    .catch(err => console.error(err));
}

原生 JS 接入

javascript 复制代码
// index.js
export async function mount(props) {
  props.container.innerHTML = `
    <h1>原生 JS 应用</h1>
    <button onclick="alert('Hello')">点击我</button>
  `;
}

七、进阶知识

🔐 应用隔离

qiankun 提供了两种隔离机制:

1. JavaScript 隔离(沙箱)

问题:子应用可能会污染全局变量

javascript 复制代码
// 子应用 A
window.userName = 'Alice';

// 子应用 B 也使用了 window.userName
console.log(window.userName); // 冲突!

qiankun 的解决方案

javascript 复制代码
start({
  sandbox: {
    strictStyleIsolation: false,  // CSS 严格隔离
    experimentalStyleIsolation: true, // CSS 实验性隔离
  },
});

qiankun 会创建一个沙箱环境,每个子应用的全局变量互不影响。

原理:使用 Proxy 拦截 window 对象的读写操作

javascript 复制代码
// 简化版原理
const fakeWindow = new Proxy(window, {
  get(target, key) {
    // 优先从子应用的作用域获取
    return sandbox[key] || target[key];
  },
  set(target, key, value) {
    // 只修改子应用的作用域
    sandbox[key] = value;
    return true;
  },
});

2. CSS 隔离

问题:子应用的样式可能互相影响

css 复制代码
/* 子应用 A */
.title { color: red; }

/* 子应用 B 也有 .title */
.title { color: blue; }

qiankun 的解决方案

方案 1:Shadow DOM(严格隔离)

javascript 复制代码
start({
  sandbox: {
    strictStyleIsolation: true,
  },
});

每个子应用被包裹在 Shadow DOM 中,样式完全隔离。

方案 2:Scoped CSS(推荐)

javascript 复制代码
start({
  sandbox: {
    experimentalStyleIsolation: true,
  },
});

qiankun 会给子应用的所有样式添加特殊前缀。

css 复制代码
/* 原始 */
.title { color: red; }

/* 转换后 */
div[data-qiankun="app1"] .title { color: red; }

📡 应用通信

子应用之间如何通信?qiankun 提供了几种方案:

方案 1:通过 initGlobalState(官方推荐)

主应用

javascript 复制代码
import { initGlobalState } from 'qiankun';

// 初始化全局状态
const actions = initGlobalState({
  user: { name: 'Alice', age: 25 },
  theme: 'light',
});

// 监听状态变化
actions.onGlobalStateChange((state, prev) => {
  console.log('状态改变了', state, prev);
});

// 修改状态
actions.setGlobalState({ theme: 'dark' });

子应用

javascript 复制代码
export async function mount(props) {
  // 获取通信方法
  props.onGlobalStateChange((state, prev) => {
    console.log('子应用收到状态', state);
  });
  
  // 修改状态
  props.setGlobalState({ user: { name: 'Bob' } });
}

方案 2:通过 props 传递

主应用

javascript 复制代码
registerMicroApps([
  {
    name: 'app1',
    entry: '//localhost:3001',
    container: '#container',
    activeRule: '/app1',
    props: {
      data: { msg: 'Hello from main app' },
      methods: {
        sayHello: () => alert('Hello!'),
      },
    },
  },
]);

子应用

javascript 复制代码
export async function mount(props) {
  console.log(props.data.msg); // 'Hello from main app'
  props.methods.sayHello();     // 调用主应用的方法
}

方案 3:通过自定义事件

javascript 复制代码
// 子应用 A 发送事件
window.dispatchEvent(new CustomEvent('app-message', {
  detail: { msg: 'Hello from App A' },
}));

// 子应用 B 接收事件
window.addEventListener('app-message', (e) => {
  console.log(e.detail.msg);
});

🚀 性能优化

1. 预加载(Prefetch)

javascript 复制代码
start({
  prefetch: true,  // 开启预加载
});

效果:在浏览器空闲时,预先加载其他子应用的资源。

场景

  • 用户在看首页时,偷偷加载商品页的资源
  • 当用户点击商品页时,瞬间展示(已经加载好了)

2. 预加载策略

javascript 复制代码
start({
  prefetch: 'all',  // 预加载所有子应用
  // prefetch: ['app1', 'app2'],  // 只预加载指定的应用
  // prefetch: (apps) => apps.filter(app => app.name !== 'heavy-app'),
});

3. 手动加载

javascript 复制代码
import { loadMicroApp } from 'qiankun';

// 手动加载一个子应用
const app = loadMicroApp({
  name: 'manual-app',
  entry: '//localhost:3001',
  container: '#manual-container',
});

// 手动卸载
app.unmount();

使用场景:弹窗、抽屉中显示子应用

4. 公共依赖提取

子应用的 webpack 配置

javascript 复制代码
module.exports = {
  externals: {
    react: 'React',
    'react-dom': 'ReactDOM',
    antd: 'antd',
  },
};

主应用提供依赖

html 复制代码
<script src="https://cdn.jsdelivr.net/npm/react@16/umd/react.production.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/react-dom@16/umd/react-dom.production.min.js"></script>

好处:子应用不打包 React,体积更小,加载更快。

🛡️ 错误处理

javascript 复制代码
import { addGlobalUncaughtErrorHandler } from 'qiankun';

// 监听全局错误
addGlobalUncaughtErrorHandler((event) => {
  console.error('子应用加载出错', event);
  
  // 显示友好的错误提示
  document.querySelector('#container').innerHTML = `
    <div style="padding: 20px; text-align: center;">
      <h2>😢 应用加载失败</h2>
      <p>请刷新页面重试</p>
    </div>
  `;
});

八、什么时候该用 qiankun

✅ 适合使用 qiankun 的场景

1. 大型企业应用

diff 复制代码
特点:
- 多个团队(5+ 个团队)
- 功能模块多(10+ 个模块)
- 需要长期维护(3+ 年)

举例:
- 企业管理系统(ERP、CRM)
- 电商后台管理
- 大型运营平台

2. 遗留系统改造

diff 复制代码
场景:
- 老系统用 jQuery 写的,想用 React 写新功能
- 不想全部重构(太贵、风险大)
- 想逐步迁移

方案:
- 老系统作为子应用
- 新功能用新技术栈开发
- 逐步替换老系统

3. 多项目整合

diff 复制代码
场景:
- 公司有多个独立的系统(订单系统、库存系统、财务系统)
- 用户需要在不同系统间切换
- 想统一入口

方案:
- 创建一个主应用作为统一入口
- 各个系统作为子应用
- 一个 URL 访问所有系统

4. 技术栈迁移

diff 复制代码
场景:
- 想从 Vue 2 升级到 Vue 3
- 又不想一次性改完(太累、风险大)

方案:
- Vue 2 项目作为子应用
- 新功能用 Vue 3 开发
- 逐步迁移

❌ 不适合使用 qiankun 的场景

1. 小型项目

diff 复制代码
特点:
- 1-2 个开发人员
- 功能简单(<10 个页面)
- 代码量少(<10000 行)

原因:
- 微前端架构增加了复杂度
- 得不偿失
- 单体应用更简单

2. 初创项目

diff 复制代码
特点:
- 刚开始做,不确定会做多大
- 需求变化快
- 追求快速迭代

原因:
- 过早优化
- 增加学习成本
- 先做起来再说

3. 性能要求极高的应用

diff 复制代码
特点:
- 追求极致性能(如游戏)
- 需要毫秒级响应

原因:
- 微前端会增加一些开销
- 应用加载、切换需要时间
- 单体应用性能更好

4. 纯展示型网站

diff 复制代码
特点:
- 官网、博客、文档站
- 没有复杂的交互
- 内容为主

原因:
- 不需要复杂架构
- 静态生成(Next.js、Gatsby)更合适
- SEO 也更好

📊 决策树

markdown 复制代码
是否使用 qiankun?

START
  ↓
项目有 5+ 个团队?
  ├─ 是 → 考虑使用 ✅
  └─ 否
      ↓
  有遗留系统需要改造?
    ├─ 是 → 考虑使用 ✅
    └─ 否
        ↓
    需要整合多个独立系统?
      ├─ 是 → 考虑使用 ✅
      └─ 否
          ↓
      项目代码量 > 50000 行?
        ├─ 是 → 考虑使用 ✅
        └─ 否 → 不建议使用 ❌

九、常见问题和解决方案

❓ FAQ

Q1: 子应用加载不出来?

可能原因

  1. 跨域问题
  2. webpack 配置不对
  3. 生命周期函数没导出

解决方案

检查 1:子应用是否允许跨域

javascript 复制代码
// webpack.config.js
devServer: {
  headers: {
    'Access-Control-Allow-Origin': '*',
  },
}

检查 2:webpack 配置

javascript 复制代码
output: {
  library: 'appName',        // ✅ 必须设置
  libraryTarget: 'umd',      // ✅ 必须设置
  publicPath: 'http://localhost:3001/', // ✅ 必须设置
}

检查 3:生命周期函数

javascript 复制代码
// ✅ 正确:使用 export
export async function mount() {}

// ❌ 错误:没有 export
async function mount() {}

Q2: 样式相互影响怎么办?

解决方案 1:开启 CSS 隔离

javascript 复制代码
start({
  sandbox: {
    experimentalStyleIsolation: true,
  },
});

解决方案 2:使用 CSS Modules

javascript 复制代码
// App.module.css
.title { color: red; }

// App.js
import styles from './App.module.css';
<div className={styles.title}>标题</div>

解决方案 3:使用 CSS-in-JS

javascript 复制代码
import styled from 'styled-components';

const Title = styled.h1`
  color: red;
`;

Q3: 子应用能独立访问吗?

可以!

javascript 复制代码
// 子应用的 index.js
if (!window.__POWERED_BY_QIANKUN__) {
  // 不在 qiankun 环境中,独立运行
  mount({});
}

这样配置后:

  • 在 qiankun 中:作为子应用运行
  • 单独访问:作为独立应用运行

Q4: 如何调试?

方法 1:Chrome DevTools

javascript 复制代码
// 主应用
console.log('主应用加载子应用', appName);

// 子应用
export async function mount(props) {
  console.log('子应用被挂载', props);
}

方法 2:使用 qiankun 的监听钩子

javascript 复制代码
registerMicroApps(apps, {
  beforeLoad: (app) => console.log('加载前', app),
  beforeMount: (app) => console.log('挂载前', app),
  afterMount: (app) => console.log('挂载后', app),
  beforeUnmount: (app) => console.log('卸载前', app),
  afterUnmount: (app) => console.log('卸载后', app),
});

方法 3:使用 React DevTools / Vue DevTools

每个子应用可以单独使用自己框架的开发工具。

Q5: 性能怎么样?

对比

指标 单体应用 qiankun 微前端
首次加载 慢(加载所有代码) 快(只加载主应用)
切换页面 快(已加载) 中等(首次需加载子应用)
内存占用 高(所有代码在内存) 低(按需加载)
开发构建 慢(项目大) 快(项目拆分了)

优化建议

  • 开启预加载
  • 提取公共依赖
  • 使用 CDN

Q6: 子应用之间能跳转吗?

可以!

方法 1:使用 history API

javascript 复制代码
// 在子应用 A 中跳转到子应用 B
history.push('/app-b/home');

方法 2:使用主应用提供的方法

javascript 复制代码
// 主应用
const props = {
  navigate: (path) => history.push(path),
};

// 子应用
export async function mount(props) {
  props.navigate('/app-b/home');
}

十、学习路线图

🎯 入门阶段(1-2 周)

第一步:理解概念

  • 什么是微前端
  • 为什么需要微前端
  • qiankun 的基本原理

第二步:动手实践

  • 跟着官方文档走一遍
  • 创建一个主应用 + 2 个子应用
  • 实现路由切换

第三步:理解配置

  • webpack 配置(library、libraryTarget)
  • 生命周期函数(bootstrap、mount、unmount)
  • 激活规则(activeRule)

推荐资源

🚀 进阶阶段(2-4 周)

第一步:深入特性

  • 应用隔离(JS 沙箱、CSS 隔离)
  • 应用通信(initGlobalState)
  • 预加载(prefetch)

第二步:接入不同框架

  • React 应用接入
  • Vue 应用接入
  • Angular 应用接入

第三步:解决实际问题

  • 解决跨域问题
  • 解决样式冲突
  • 优化加载性能

推荐资源

🏆 高级阶段(1-2 个月)

第一步:深入源码

  • 阅读 qiankun 源码
  • 理解沙箱实现原理
  • 理解应用加载机制

第二步:生产环境实践

  • 部署策略
  • 监控和错误处理
  • 性能优化

第三步:架构设计

  • 设计合理的应用拆分
  • 设计统一的规范
  • 设计通信机制

推荐资源

📚 推荐阅读

文章

视频

  • B 站搜索:"qiankun 微前端教程"
  • YouTube 搜索:"qiankun micro frontend"

源码


🎓 总结

核心要点回顾

1. qiankun 是什么?

  • 阿里开源的微前端框架
  • 用于将大应用拆分成多个小应用
  • 技术栈无关,支持 React、Vue、Angular 等

2. 为什么用 qiankun?

  • 团队协作更容易(独立开发、独立部署)
  • 技术栈更灵活(可以混用)
  • 风险更可控(一个应用挂了不影响其他)
  • 性能更好(按需加载)

3. 怎么用 qiankun?

javascript 复制代码
// 主应用
import { registerMicroApps, start } from 'qiankun';
registerMicroApps([{ name, entry, container, activeRule }]);
start();

// 子应用
export async function bootstrap() {}
export async function mount(props) {}
export async function unmount(props) {}

4. 什么时候用 qiankun?

  • ✅ 大型项目(多团队、多模块)
  • ✅ 遗留系统改造
  • ✅ 多项目整合
  • ❌ 小型项目(过度设计)
  • ❌ 初创项目(过早优化)

🎯 一句话总结

qiankun 就像一个剧院管理系统,让不同的剧目(子应用)可以在同一个舞台(主应用)上轮流表演,互不干扰,按需上场。

💡 最后的建议

  1. 不要为了微前端而微前端

    • 先评估是否真的需要
    • 简单场景用简单方案
  2. 从小做起

    • 先做一个简单的 demo
    • 验证可行性
    • 再逐步推广
  3. 制定规范

    • 统一的命名规范
    • 统一的通信方式
    • 统一的错误处理
  4. 持续优化

    • 监控性能
    • 收集反馈
    • 不断改进

🚀 下一步

现在就开始

bash 复制代码
# 1. 创建你的第一个微前端应用
mkdir my-first-qiankun
cd my-first-qiankun

# 2. 阅读官方文档
open https://qiankun.umijs.org/

# 3. 查看示例代码
git clone https://github.com/umijs/qiankun.git
cd qiankun/examples

# 4. 动手实践
npm install
npm start

记住

  • 💪 学习最好的方式是动手实践
  • 🤔 遇到问题多思考、多查文档
  • 📖 多看优秀的开源项目
  • 🔄 持续迭代、不断优化

祝你学习愉快!加油!🎉

有任何问题,欢迎:

相关推荐
weixin_3823952317 分钟前
为小工厂量身打造:本地部署的物料管理系统带缺料计算
前端·制造
__zRainy__23 分钟前
解决pnpm v10+不自动构建
前端·pnpm·工程化
猫猫不是喵喵.1 小时前
Vue3 Props 属性
前端·javascript·vue.js
醉城夜风~2 小时前
CSS元素显示模式(display)
前端·css
AI大模型-小华3 小时前
Codex 三方充值快速入门指南
java·前端·数据库·chatgpt·ai编程·codex·chatgpt pro
做前端的娜娜子5 小时前
同一链接实现 PC Web 与移动 H5 自适应
前端·掘金·金石计划
小帅不太帅5 小时前
架构没变、规模没变,DeepSeek V4 Flash 正式版凭什么暴涨 47 分?
前端·aigc·deepseek
jarvisuni6 小时前
DeepSeekFlash前端依旧拉垮,而且变慢了很多!
前端·javascript·算法
卷福同学7 小时前
AI编程出海第二步:验证关键词能否做站
前端·人工智能·后端