微前端 - qiankun 入门到实践——第六节:子应用集成

954 阅读3分钟

在本节中,我们将详细介绍如何配置和集成子应用到主应用中。子应用将是独立的React 18项目,通过Qiankun框架与主应用集成。以下步骤将指导你完成子应用的创建、配置和集成过程。

创建子应用

每个子应用也是一个Vite+React 18项目。我们将创建一个子应用,并配置它以支持微前端架构。

  1. 初始化子应用

  2. 创建并初始化一个新的Vite项目作为子应用:

    npm create vite@latest sub-app-1 --template react-ts cd sub-app-1 npm install

  3. 子应用的文件结构:

    sub-app-1/ ├── public/ ├── src/ │ ├── App.tsx │ ├── main.tsx │ ├── index.css ├── index.html ├── package.json └── vite.config.ts

  4. 配置子应用的生命周期函数

修改子应用的main.tsx以支持作为微前端应用启动:

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

function render(props: any) {
  const { container } = props;
  const root = ReactDOM.createRoot(container ? container.querySelector('#root') : document.querySelector('#root'));
  root.render(
    <React.StrictMode>
      <App />
    </React.StrictMode>
  );
}

if (!window.__POWERED_BY_QIANKUN__) {
  render({});
}

export async function bootstrap() {
  console.log('React app bootstraped');
}

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

export async function unmount(props: any) {
  const { container } = props;
  const root = container ? container.querySelector('#root') : document.querySelector('#root');
  ReactDOM.unmountComponentAtNode(root);
}
  1. 配置Vite支持跨域加载

vite.config.ts中配置CORS支持,以便主应用可以加载子应用的资源:

// vite.config.tsimport { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';

export default defineConfig({plugins: [react()],server: {port: 7100,cors: true,
  },
});
  1. 添加基本组件

创建一个简单的子应用页面:

// vite.config.ts
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';

export default defineConfig({
  plugins: [react()],
  server: {
    port: 7100,
    cors: true,
  },
});

集成子应用到主应用

  1. 启动子应用

sub-app-1目录下启动子应用:

npm run dev
  1. 注册子应用

在主应用中使用Qiankun的registerMicroApps方法注册子应用,并启动Qiankun。

// src/App.tsx
import React, { useEffect } from 'react';
import { Link, Route, Routes } from 'react-router-dom';
import { registerMicroApps, start } from 'qiankun';
import Home from './pages/Home';
import About from './pages/About';

const App = () => {
  useEffect(() => {
    registerMicroApps([
      {
        name: 'sub-app-1',
        entry: '//localhost:7100', // 子应用入口
        container: '#subapp-container',
        activeRule: '/subapp1',
      },
    ]);
    start();
  }, []);

  return (
    <div>
      <nav>
        <ul>
          <li><Link to="/">Home</Link></li>
          <li><Link to="/about">About</Link></li>
          <li><Link to="/subapp1">Sub App 1</Link></li>
        </ul>
      </nav>
      <Routes>
        <Route path="/" element={<Home />} />
        <Route path="/about" element={<About />} />
        <Route path="/subapp1/*" element={<div id="subapp-container"></div>} />
      </Routes>
    </div>
  );
};

export default App;
  1. 测试集成

访问主应用的URL,导航到/subapp1路径,应该会看到子应用1的内容被正确加载。

高级配置

  1. 样式隔离

子应用的样式可能会与主应用冲突。可以使用CSS Module、Shadow DOM或者在CSS选择器中加入应用特定的前缀。

  1. 通信机制

使用自定义事件或全局状态管理库(如Redux)实现主应用与子应用之间的通信。

  1. 性能优化

采取懒加载子应用、代码分割、资源预加载等策略优化启动性能。

  1. 安全性

采用内容安全策略(CSP)和沙箱环境等技术降低安全风险。

示例代码

完整的主应用代码示例:

// src/App.tsx
import React, { useEffect } from 'react';
import { Link, Route, Routes } from 'react-router-dom';
import { registerMicroApps, start } from 'qiankun';
import Home from './pages/Home';
import About from './pages/About';

const App = () => {
  useEffect(() => {
    registerMicroApps([
      {
        name: 'sub-app-1',
        entry: '//localhost:7100', // 子应用入口
        container: '#subapp-container',
        activeRule: '/subapp1',
      },
    ]);
    start();
  }, []);

  return (
    <div>
      <nav>
        <ul>
          <li><Link to="/">Home</Link></li>
          <li><Link to="/about">About</Link></li>
          <li><Link to="/subapp1">Sub App 1</Link></li>
        </ul>
      </nav>
      <Routes>
        <Route path="/" element={<Home />} />
        <Route path="/about" element={<About />} />
        <Route path="/subapp1/*" element={<div id="subapp-container"></div>} />
      </Routes>
    </div>
  );
};

export default App;

子应用代码示例:

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

function render(props: any) {
  const { container } = props;
  const root = ReactDOM.createRoot(container ? container.querySelector('#root') : document.querySelector('#root'));
  root.render(
    <React.StrictMode>
      <App />
    </React.StrictMode>
  );
}

if (!window.__POWERED_BY_QIANKUN__) {
  render({});
}

export async function bootstrap() {
  console.log('React app bootstraped');
}

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

export async function unmount(props: any) {
  const { container } = props;
  const root = container ? container.querySelector('#root') : document.querySelector('#root');
  ReactDOM.unmountComponentAtNode(root);
}

通过本节内容,我们已经了解了如何创建和配置子应用,并将其集成到主应用中。我们还介绍了样式隔离、通信机制、性能优化和安全性等高级配置。下一步,我们将继续探索子应用之间的通信和状态管理。