乾坤

来看这篇文章的我就不赘述乾坤是什么了
乾坤官网

qiankun 是一个基于 single-spa 的微前端实现库,旨在帮助大家能更简单、无痛的构建一个生产可用微前端架构系统。

背景介绍

需要将几个系统做整合,以一个应用为父应用,其余的应用为子应用
我这里的应用都是react的应用,市面上很多应用都是用vue来打样的
我这里仅仅只是入门,很多功能还没用上,比如父子应用通讯,一些已知的问题也没解决,比如样式兼容问题,后续会更新在使用乾坤中碰到的问题,如果有旁友在react项目中入门配置时碰到问题,可以私信找我,希望能够减少大家踩坑的时间

乾坤-常见问题

实践
  1. 父应用安装乾坤,注册子应用
// main.js 父应用的入口文件
import {registerMicroApps, start} from 'qiankun'

const entryMap = {
    'development': '//localhost:8080',
    'fat': 'xxxxxxfat环境下的域名',
}
// 定义要整合的微应用列表
const apps = [
      {
        name: 'xxxxx子应用',
        entry: entryMap[process.env.REACT_NODE_ENV],
        container: '#test', // 这里是父应用中,你想把子应用挂载的地方
        activeRule: '/react_sub', // 父应用中你想访问的子应用的地址
        props: {id: 'test'} // 传给子应用的参数
      },
];

// // 注册应用
registerMicroApps(apps);
// 开启应用
start();
  1. 子应用中需要暴露生命周期
    mount bootstrap unmount 这些生命周期都需要暴露
// main.js 子应用的入口文件
// 这里子应用需要包裹一层,否则父应用访问的时候会有问题
if (!window.__POWERED_BY_QIANKUN__) {
  ReactDOM.render(
  <ConfigProvider locale={zhCN}>
    <Router>
      <App />
    </Router>
  </ConfigProvider>,
  document.getElementById('root'),
  );
}


// eslint-disable-next-line
export const mount = (props:any) => Promise.resolve().then(() => {
  // eslint-disable-next-line
  console.log('mount', props, !!props.container);
  ReactDOM.render(
      <ConfigProvider locale={zhCN}>
        <Router>
          <App />
        </Router>
        </ConfigProvider>,
    props.container ? props.container.querySelector('#root') : document.getElementById('root'), // eslint-disable-line
  );
});

// eslint-disable-next-line
export async function bootstrap() {
// eslint-disable-next-line
  console.log('react app bootstraped');
}


/**
 * 应用每次 切出/卸载 会调用的方法,通常在这里我们会卸载微应用的应用实例
 */
// eslint-disable-next-line
export async function unmount(props: any) {
  ReactDOM.unmountComponentAtNode(
    props.container ? props.container.querySelector('#root') : document.getElementById('root'), // eslint-disable-line
  );
}

  1. 配置webpack跨域
  devServer: {
   	....
    headers: {
      "Access-Control-Allow-Origin": "*",
      "Access-Control-Allow-Methods": "*",
      "Access-Control-Allow-Headers": "*"
    },
    .....
    }
  1. webpack 需要配置output 为了父应用辨识资源
    我这里写的都是在配置中需要注意的
    publicPath:需要写绝对路径,否则父应用获取静态资源时会异常
    如果是你使用的是webpack4,配置jsonpFunction
    如果你使用的是webpack5,配置chunkLoadingGlobal
output: {
  publicPath: `${process.env.REACT_APP_ENV === 'dev' ? '//localhost:8080' : publicURL }/`,
  ...
  library: `${packageName}-[name]`,
  libraryTarget: 'umd',
  chunkLoadingGlobal: `webpackJsonp_${packageName}`,  // webpack5
  jsonpFunction: `webpackJsonp_${packageName}`,  // webpack4
  ....
},
  1. 子应用的请求路径,写绝对路径,不要用相对路径,开发环境时就由父应用的域名发出请求了

  2. 父应用的activeRule,最好和子应用的路由保持一致,或者在子应用新配置一个和activeRule一样的路由,要不然会匹配不上

  3. 父子应用样式隔离
    -----9.21更新------
    处理子应用框架系统是vue的时候遇到的一些问题

  4. 路由问题
    在父应用切换路由,从子应用的某个页面切换到父应用某个页面的碰到一个问题。
    触发切换动作更新父应用页面,在子应用卸载unmount之前,这样就会有白屏的问题
    我这边在子应用导出的unmount方法里面调用了location.reload暴力解决了下,还没来得及深究

我在配置乾坤时见到的报错
1.Application died in status LOADING_SOURCE_CODE
子应用的入口文件有问题,看看是不是生命周期导出的有问题
没问题的话,看看是不是原来的render,没有用if(!window.POWERED_BY_QIANKUN)包裹住
2.Application died in status NOT_MOUNTED:Target container is not a DOM element
看下是不是子应用入口文件的mount钩子,render的第二个参数有问题,打印下props.container看下
3.TypeError: Cannot read properties of null (reading ‘onerror’)
静态资源访问有问题,看看publicPath配绝对路径了没
4.ChunkLoadError:Loading chunk 0 failed
看看publicPath配绝对路径了没
5.you need to export lifecycle functions
没导出生命周期,看看是否把该导出的生命周期都导出了,如果都导出了,研究下是否是写错文件了,需要在子应用的入口文件处导出
6. tips:看报错的status后面跟着啥,比如UNMOUNTING,就是在子应用的unmount里面找问题

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐