【微前端】qiankun基础

【微前端】qiankun 使用指南:从零搭建微前端项目

    • 一、什么是微前端
      • [1.1 概念](#1.1 概念)
      • [1.2 核心价值](#1.2 核心价值)
      • [1.3 为什么不用 iframe?](#1.3 为什么不用 iframe?)
    • [二、qiankun 简介](#二、qiankun 简介)
      • [2.1 什么是 qiankun](#2.1 什么是 qiankun)
      • [2.2 特性](#2.2 特性)
    • 三、快速上手
      • [3.1 项目结构](#3.1 项目结构)
      • [3.2 主应用配置](#3.2 主应用配置)
      • [3.3 微应用配置](#3.3 微应用配置)
    • 跨域问题

技术栈:qiankun + React + Webpack

一、什么是微前端

1.1 概念

微前端就是把一个超大型应用 拆分成多个独立开发、独立部署、独立运行的小应用,再通过主应用把它们整合起来。

1.2 核心价值

特性 说明
技术栈无关 主框架不限制接入应用的技术栈,微应用具备完全自主权
独立开发、独立部署 微应用仓库独立,前后端可独立开发,部署完成后主框架自动完成同步更新
增量升级 微前端是一种非常好的实施渐进式重构的手段和策略
独立运行时 每个微应用之间状态隔离,运行时状态不共享

1.3 为什么不用 iframe?

iframe 不是也能实现吗?能,但问题不少:

  • url 不同步:刷新后 iframe url 状态丢失
  • UI 不同步:DOM 结构不共享,弹窗只能在 iframe 内部显示
  • 全局上下文完全隔离:内存变量不共享,Cookie、LocalStorage 不互通
  • :每次子应用进入都是一次浏览器上下文重建、资源重新加载

二、qiankun 简介

2.1 什么是 qiankun

qiankun 是蚂蚁基于single-spa封装的微前端库。

2.2 特性

  • 任意前端框架,React/Vue/Angular/JQuery 都能接入
  • 样式隔离,微应用之间样式不会互相污染
  • JS 沙箱,全局变量/事件隔离,不怕冲突
  • 资源预加载,浏览器空闲时提前加载,切换更快

三、快速上手

3.1 项目结构

bash 复制代码
micro-frontend/
├── main-app/          # 主应用(基座)
└── micro-react/       # 微应用 - React

3.2 主应用配置

安装 qiankun

bash 复制代码
yarn add qiankun

注册微应用

在主应用入口文件中配置:

javascript 复制代码
// main-app/src/index.js
import React from 'react'
import ReactDOM from 'react-dom/client'
import { registerMicroApps, start } from 'qiankun'
import './index.css'

// 注册微应用
registerMicroApps([
  {
    name: 'm-app',
    entry: 'http://localhost:8001',
    container: '#subapp-container',
    activeRule: '/',
  }
])

// 启动 qiankun
start()

// 渲染容器
ReactDOM.createRoot(document.getElementById('root')!).render(
  <React.StrictMode>
    <div id="subapp-container"></div>
  </React.StrictMode>
)

主应用 HTML 结构

html 复制代码
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>微前端主应用</title>
</head>
<body>
  <div id="root"></div>
</body>
</html>

3.3 微应用配置

修改入口文件

javascript 复制代码
// micro-react/src/index.js
import React from 'react'
import ReactDOM from 'react-dom/client'
import App from './App'
import './index.css'

let root: ReactDOM.Root | null = null

// 渲染函数
function render(props: any = {}) {
  const { container } = props
  const rootElement = container 
    ? container.querySelector('#root') 
    : document.getElementById('root')
  
  if (rootElement) {
    root = ReactDOM.createRoot(rootElement)
    root.render(
      <React.StrictMode>
        <App {...props} />
      </React.StrictMode>
    )
  }
}

// 判断是否在 qiankun 环境中运行
if (!(window as any).__POWERED_BY_QIANKUN__) {
  render()
}

// 导出 qiankun 生命周期函数
export async function bootstrap() {
  console.log('[React子应用] bootstrap')
}

export async function mount(props: any) {
  render(props)
}

export async function unmount() {
  root?.unmount()
  root = null
}

修改 webpack 配置

javascript 复制代码
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const packageName = require('./package.json').name;

module.exports = {
  entry: './src/index.tsx',
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'bundle.[contenthash].js',
    clean: true,
    // qiankun 子应用必须配置
    library: `${packageName}-[name]`,
    libraryTarget: 'umd',
    chunkLoadingGlobal: `webpackJsonp_${packageName}`,
    globalObject: 'window',
  },
  resolve: {
    extensions: ['.tsx', '.ts', '.js', '.jsx'],
  },
  module: {
    rules: [
      {
        test: /\.(ts|tsx|js|jsx)$/,
        exclude: /node_modules/,
        use: {
          loader: 'babel-loader',
          options: {
            presets: [
              '@babel/preset-env',
              ['@babel/preset-react', { runtime: 'automatic' }],
              '@babel/preset-typescript',
            ],
          },
        },
      },
      {
        test: /\.css$/,
        use: ['style-loader', 'css-loader'],
      },
    ],
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: './public/index.html',
      title: 'React 子应用',
    }),
  ],
  devServer: {
    port: 8001,
    hot: true,
    historyApiFallback: true,
    headers: {
      'Access-Control-Allow-Origin': '*',
    },
  },
};

跨域问题

注意:微应用必须开启 CORS,不然主应用加载不了

javascript 复制代码
// webpack devServer 配置
devServer: {
  headers: {
    'Access-Control-Allow-Origin': '*',
  }
}
相关推荐
anOnion8 分钟前
构建无障碍组件之Alert Dialog Pattern
前端·html·交互设计
choke23315 分钟前
[特殊字符] Python 文件与路径操作
java·前端·javascript
云飞云共享云桌面18 分钟前
高性能图形工作站的资源如何共享给10个SolidWorks研发设计用
linux·运维·服务器·前端·网络·数据库·人工智能
Deng94520131430 分钟前
Vue + Flask 前后端分离项目实战:从零搭建一个完整博客系统
前端·vue.js·flask
威迪斯特33 分钟前
Flask:轻量级Web框架的技术本质与工程实践
前端·数据库·后端·python·flask·开发框架·核心架构
wuhen_n1 小时前
JavaScript内置数据结构
开发语言·前端·javascript·数据结构
大鱼前端1 小时前
为什么我说CSS-in-JS是前端“最佳”的糟粕设计?
前端
不爱吃糖的程序媛1 小时前
Capacitor:跨平台Web原生应用开发利器,现已全面适配鸿蒙
前端·华为·harmonyos
AC赳赳老秦1 小时前
2026国产算力新周期:DeepSeek实战适配英伟达H200,引领大模型训练效率跃升
大数据·前端·人工智能·算法·tidb·memcache·deepseek
CHU7290351 小时前
淘宝扭蛋机抽盒小程序前端功能解析:解锁趣味抽盒新体验
前端·小程序