【微前端】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': '*',
  }
}
相关推荐
摸鱼的春哥2 小时前
企业自建低代码平台正在扼杀AI编程的生长
前端·javascript·后端
-凌凌漆-2 小时前
【JS】var与let的区别
开发语言·前端·javascript
火车叼位2 小时前
使ast-grep-vscode 识别Vue组件
前端·visual studio code
YAY_tyy2 小时前
综合实战:基于 Turfjs 的智慧园区空间管理系统
前端·3d·cesium·turfjs
生活在一步步变好i2 小时前
模块化与包管理核心知识点详解
前端
午安~婉2 小时前
整理Git
前端·git
千寻girling2 小时前
Vue.js 前端开发实战 ( 电子版 ) —— 黑马
前端·javascript·vue.js·b树·决策树·随机森林·最小二乘法
程序员爱钓鱼2 小时前
Node.js 编程实战:博客系统 —— 数据库设计
前端·后端·node.js
m0_741412242 小时前
Webpack:F:\nochinese_path\React_code\webpack
前端·react.js·webpack