qiankun微前端

98 阅读3分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第8天,点击查看活动详情

最近着手的内部项目,在公司内部高调的宣传了一番,反响强烈,有些部门想和我们深度合作,实现共荣。由于我是前端大拿(项目由两人搭建,稳定后,我一人维护),所以和对面对接,对接过程中,我让对方给个案例,对方说,就是想按照微前端的方法接入,我当时没惯着,我说我不会微前端(由于礼貌我说我不了解)。 周末了解了一会,真香,感觉真不赖

介绍

qiankun 是一个基于 single-spa 的微前端实现库,旨在帮助大家能更简单、无痛的构建一个生产可用微前端架构系统。 我感觉官网文档写的可以,和我们内部应用文档也不相上下,中国人的文档和笔记一样,都是给自己看的。

使用方式 (测试 )

步骤 1

首先要有一个主应用,微前端就是很多项目搞到一个项目里,当前要有一个主应用,嵌套进来的都是子应用,当然官方叫法是微应用, 创建一个文件夹,在里面创建3个react项目(为什么是react项目呢?因为我暂时使用的是react技术栈,我还没看vue嵌入), base是主应用,kun1和kun2是子应用 为了节省时间,开三个终端

npx create-react-app base

npx create-react-app kun1

npx create-react-app kun2

修改项目启动的端口号,在项目根目录下创建.env文件

PORT=5001

base项目中.env是PORT=5001 kun1:PORT=5002 kun2:PORT=5003

步骤 2 (2-3主应用里的配置)

在主应用里安装qiankun

yarn add qiankun

步骤 3

在主应用中注册微应用 index.js中顶部插入如下代码


import { registerMicroApps, start } from 'qiankun';


registerMicroApps([
  {
    // 项目名称
    name: 'kun1', // app name registered
    // 微应用入口
    entry: '//localhost:5002',
    // 挂载点,必须是存在主应用中的真实节点
    container: '#kun1',
    // 路由匹配时显示该应用
    activeRule: '/kun1',
  
  },
  {
    name: 'kun2',
    entry: '//localhost:5003',
    container: '#kun2',
    activeRule: '/kun2',
   
  },
]);


start();

步骤4 (4-5微应用里做的配置)

kun1和kun2(两个都要搞) 安装 react-app-rewired 改写webpack配置,无需 npm run eject弹出配置就能改 官网安的插件是 @rescripts/cli

yarn add react-app-rewired

根目录增加 config-overrides.js

module.exports = {
    webpack: (config) => {
        config.output.library = 'kun2';
        config.output.libraryTarget = 'umd';
        config.output.globalObject = 'window';
        return config;
    },
    devServer: (_) => {
        const config = _;
        config.headers = {
            "Access-Control-Allow-Origin": "*"
        };
        config.historyApiFallback = true;
        config.hot = false;
        config.watchContentBase = false;
        config.liveReload = false;
        return config;
    }
}

修改 package.json

    "start": "react-app-rewired start",
    "build": "react-app-rewired build",
    "test": "react-app-rewired test",
    "eject": "react-app-rewired eject"

步骤5

导出相应的生命周期

import './public-path'
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
function render(props) {
  const { container } = props;
  // react升级到18后,官网的写法会报错
  const root = ReactDOM.createRoot(container ? container.querySelector('#root') : document.querySelector('#root'));
  root.render(<App />);
}

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

export async function bootstrap() {
  console.log('[react16] react app bootstraped');
}

export async function mount(props) {
  console.log('[react16] props from main framework', props);
  render(props);
}

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

步骤6

因为项目里都是相对路径,所有微应用获取静态资源时是相对于主应用的当前目录,所有要配置成绝对路径,完整的路径,因为都是用的同一文件名,所以demo里体现不到,可以尝试把主应用中图logo图片删除,当然App里引用部分也删掉,再次启动效果后就可以看到图片加载失败 kun1和kun2项目的创建 /src/public-path.js

if (window.__POWERED_BY_QIANKUN__) {
   window.__webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__;
 }

kun1和kun2项目的入口文件index.js中顶部增加一句,就把这个配置好了

import './public-path'

重启kun1和kun2,图片等静态资源就可以正常加载了,查看dom,可以看到资源路径是绝对路径了

image.png