umi+plugin-qiankun 微应用前端实践含源码

·  阅读 2450
umi+plugin-qiankun 微应用前端实践含源码

准备两个应用

初始化主应用

使用 pro 来快速的初始化主应用。

npm i @ant-design/pro-cli -g
pro create app

复制代码

选择版本

image.png

安装依赖:

$ cd app && yarn 
$ yarn add @umijs/plugin-qiankun -D
复制代码
  • PS 如果安装报错:error An unexpected error occurred ,请检查 npm 设置

image.png

  • 设置为官方源
npm config set registry http://registry.npmjs.org

复制代码

配置主应用

配置子应用路由 config/routes.ts

image.png

{
    name: 'subapp',
    path: '/subapp',
    microApp: 'subapp',
    access: 'normalRouteFilter'
  },
复制代码

开启 Umi UI(可选):

// 打开开发模式下页面右下角的小气泡,方便添加区块和模版等pro资产
$ tyarn add @umijs/preset-ui -D
// 或
$ npm install --save-dev @umijs/preset-ui
复制代码

初始化子应用

mkdir subapp && cd subapp
yarn create @umijs/umi-app 
复制代码

package.json 设置名称

{
  "name":"subapp",
}
复制代码

配置子应用

安装依赖

yarn add @umijs/plugin-qiankun -D
复制代码

配置子应用.umirc.ts

qiankun: {
    slave: {},
},
复制代码

设置端口号.env

设置固定的端口号,可以固定路径,方便后面的配置使用

PORT=8002

复制代码

连接父子应用

在主应用 app 的 config/config.ts 添加配置

qiankun: {
    master: {
      apps: [
        {
          name: 'subapp',
          entry: 'http://localhost:8002'
        }
        ]
    }
}
复制代码
  • 启动项目后,页面一直loading 需调整页面结构

image.png

  • 由于添加了qiankun ,dom结构发生了变化,需要将替换root 为 root-master

image.png

测试子应用路由的使用

  • 补充子应用路由 .umirc.ts
  routes: [
    {
      path: '/', component: '@/pages/index',
      routes: [
        {
          path: '/child1',
          component: '@/pages/Child1',
        },
        {
          path: '/child2',
          component: '@/pages/Child2',
        },
      ],
    },
  ],
复制代码
  • 调整页面结构 src/pages/index.tsx
import { Link } from 'umi';
import styles from './index.less';

export default function IndexPage(props) {
  return (
    <div>
      <div style={{ background: '#fff', padding: 10 }}>
        子应用公共布局
        <Link to='/child1'>child1</Link>
      </div>
      {props.children}
    </div>
  );
}

复制代码
  • 添加嵌套页面 src/pages/Child1.tsx
import { Link } from 'umi'

function Child1() {
  return (
    <div>
      Child1
      <br />
      <div>
        <Link to='/child2'>前往Child2</Link>
      </div>
      <br />
      <div>
        <Link to='/'>返回子应用主页subapp</Link>
      </div>
    </div>
  )
}

export default Child1


复制代码
  • 添加嵌套页面 src/pages/Child2.tsx

import React from 'react'

function Child2() {
  return (
    <div>我是Child2</div>
  )
}

export default Child2


复制代码

路由效果展示

Sep-01-2022 16-08-37.gif

父子级通信

需确保已安装 @umijs/plugin-model 或 @umijs/preset-react

父应用安装

yarn add @umijs/plugin-model @umijs/preset-react
复制代码

父级:src/app.tsx

// 添加子应用初始参数
export function useQiankunStateForSlave() {
  const [masterState, setMasterState] = useState<{ name: string }>();
  useEffect(() => {
    setMasterState({ name: '我是app的数据来给subapp比个✌️' });
  }, []);
  return {
    masterState,
    setMasterState
  }
}
复制代码

子集调用 src/pages/index.tsx

import { Link, useModel, } from 'umi';
import { Button, Space } from 'antd'
export default function IndexPage(props) {
  const masterProps = useModel('@@qiankunStateFromMaster');
  return (
    <div>
      <div style={{ background: '#fff', padding: 10 }}>
        <Space>
          子应用公共布局
          <Link to='/child1'>child1</Link>
          <Button onClick={() => {
            masterProps?.setMasterState({ name: 'subapp修改了数据' })
          }}>修改主应用数据</Button>
        </Space>
      </div>
      <div>{masterProps?.masterState?.name}</div>
      {props.children}
    </div>
  );
}
复制代码

父子通信展示

Sep-01-2022 16-53-31.gif

部署时的跨域问题

本地访问的时候,使用localhost是可以正常访问,部署到测试环境出现CORS跨域问题,解决方案是通过配置子应用的Nginx 来解决。

server {  // ....此处省略

        location / {
           add_header 'Access-Control-Allow-Origin' '*';
           add_header 'Access-Control-Allow-Credentials' 'true';
           add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
           add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
           index index.html index.htm;
        }
    }
复制代码

路由权限[access]

子项目应如何设置路由权限,即如果没有权限访问子应用的页面,应在路由上直接拦截,返回到403页面。

  • 首先,父应用应针对子应用设置权限,以subapp项目为例:
const routes = [
  //....
  {
    name: 'subapp',
    path: '/subapp',
    microApp: 'subapp',
    access: 'normalRouteFilter' // 设置权限校验
  },
  ]
复制代码
  • 其次,在子应用中配置access.ts 文件。
  • 子应用添加 layout 配置
layout: {
    name: 'Matrix 矩阵',
    locale: false,
    siderWidth: 0,
    // 不展示顶栏
    headerRender: false,
    // 不展示页脚
    footerRender: false,
    // 不展示菜单
    menuRender: false,
    // 不展示菜单顶栏
    menuHeaderRender: false,
    disableContentMargin: false,
    flatMenu: true,
  }
复制代码

参考

分类:
前端
收藏成功!
已添加到「」, 点击更改