npm package: @ks-dilu/react
Description: 的卢微前端React主应用SDK
Author: ybbjegj
Latest version: 0.1.4

## @ks-dilu/react

的卢微前端 React 版本的主应用组件化 SDK，分别从`路由级` `组件级`子应用视角出发，介绍如何通过 SDK 来将应用接入微前端框架


## 安装依赖

```
npm install @ks-dilu/react --save
yarn add @ks-dilu/react
```

## 路由级 DLRouter

**DEMO**

```tsx
import {createRoot} from 'react/client';
import { DLRouter } from '@ks-dilu/react';


const micros = [{
  activeRule: '/zone';
  entry: 'https://xxx.cdn.com/xx',
  name: 'test1',
},{
  activeRule: '/zone';
  entry: 'https://xxx.cdn.com/xx',
  name: 'test1'
}]

const App = () => {
  return (
    <DLRouter
      fetchMicros={async () => {
        return micros;
      }}
    ></DLRouter>
  );
};

const container = createRoot(document.getElementById('main_root_id'));

container.render(<App/>)

```

通过上面的 Demo 可以非常方便的完成主应用的接入微前端框架, 并且路由劫持，根据激活规则展现子应用；

**Props**

属性说明如下

| 属性 | 说明 | 类型 | 默认值 | 必填 |
| --- | --- | --- | --- | --- |
| extra | 会透传给子应用，配合@ks-dilu/react-micro 可以实现子应用数据通信 | object |  | 否 |
| loader | 状态发生变化时会调用的方法 | function |  | 否 |
| defaultMountAppLink | 设置主应用启动后默认进入的微应用 | string |  | 否 |
| containerId | 容器 Id | string |  | 否，配合 isOccupyOuterContainer = true 时,需要指定，并且该 ID 的 Dom 要存在 |
| isOccupyOuterContainer | 是否使用外部定义的容器 DOM 节点 | string | false | 否 |
| collect | 日志收集函数 | CollectLogFn | (type, opts) => void | 否 |
| activeFilter | 子应用激活过滤器，必须是同步纯函数 | ActivityFn |  | 否 |
| onBeforeLoad | 子应用开始加载前触发 | function |  | 否 |
| onBeforeMount | 子应用开始挂载前触发 | function |  | 否 |
| onAfterMount | 子应用挂载完成触发 | function |  | 否 |
| onBeforeUnmount | 子应用开始卸载销毁前触发 | function |  | 否 |
| onAfterUnmount | 子应用卸载销毁触发 | function |  | 否 |
| onFirstMount | 第一个子应用 mount 调用 | function |  | 否 |
| onError | 添加全局的未捕获异常处理器 | function |  | 否 |
| advanced | qiankun 的高级配置 | Advanced |  | 否 |
| fetchMicros | 获取要注册的子应用 | async () => MicroInfo[] |  | 是 |

## 组件级 DLWidget

**DEMO**

```tsx
import {createRoot} from 'react/client';
import { DLRouter } from '@ks-dilu/react';


const micros = [{
  activeRule: '/zone';
  entry: 'https://xxx.cdn.com/xx',
  name: 'test1',
},{
  activeRule: '/zone';
  entry: 'https://xxx.cdn.com/xx',
  name: 'test1'
}]

const App = () => {
  return (
    <DLWidget
      entry = 'https://xxx.cdn.com/xx'
      name = 'test1'
    ></DLWidget>
  );
};

const container = createRoot(document.getElementById('main_root_id'));

container.render(<App/>)

```

通过上面的 Demo，可以手动加载指定的子应用；

**Props**

属性说明如下

| 属性 | 说明 | 类型 | 默认值 | 必填 |
| --- | --- | --- | --- | --- |
| extra | 会透传给子应用，配合@ks-dilu/react-micro 可以实现子应用数据通信 | object |  | 否 |
| loader | 状态发生变化时会调用的方法 | function |  | 否 |
| collect | 日志收集函数 | CollectLogFn | (type, opts) => void | 否 |
| onBeforeLoad | 子应用开始加载前触发 | function |  | 否 |
| onBeforeMount | 子应用开始挂载前触发 | function |  | 否 |
| onAfterMount | 子应用挂载完成触发 | function |  | 否 |
| onBeforeUnmount | 子应用开始卸载销毁前触发 | function |  | 否 |
| onAfterUnmount | 子应用卸载销毁触发 | function |  | 否 |
| onError | 添加全局的未捕获异常处理器 | function |  | 否 |
| name | string | 唯一的标识 |  | 是 |
| entry | Entry | 唯一的标识 |  | 是 |
| advanced | qiankun 的高级配置 | Advanced |  | 否 |

## Props 中类型说明

Advanced 说明

| 属性 | 说明 | 类型 | 默认值 | 必填 |
| --- | --- | --- | --- | --- |
| prefetch | 是否开启预加载， 仅仅用于路由级子应用时生效 | boolean | false |  |
| fetch | 自定义的 fetch 方法 | function | - |  |
| sandbox | 是否开启沙箱 | boolean 或 `{strictStyleIsolation?: boolean, experimentalStyleIsolation?: boolean}` | true |  |
| singular | 是否为单实例场景，单实例指的是同一时间只会渲染一个微应用 | boolean | true |  |
| excludeAssetFilter | 指定部分特殊的动态加载的微应用资源（css/js) 不被 qiankun 劫持处理 | function |  |  |
| getPublicPath | 参考 [qiankun](https://qiankun.umijs.org/zh/api#startopts) | function |  |  |
| getTemplate | 通过自己实现的 getTemplate 方法过滤微应用 HTML 模板中的异常脚本 | function |  |  |

```typescript
// 参考乾坤文档
export interface Advanced {
  /**
   * 是否开启沙箱，默认为 true
   */
  sandbox?:
    | boolean
    | {
        strictStyleIsolation?: boolean;
        experimentalStyleIsolation?: boolean;
      };
  singular?: boolean | ((app: RegistrableApp<any>) => Promise<boolean>);
  excludeAssetFilter?: (url: string) => boolean;
  getPublicPath?: (entry: string) => string;
  getTemplate?: (tpl: string) => string;
  fetch?: (url: RequestInfo | URL, init?: RequestInit) => Promise<any>;
  /**
   * 仅仅用于路由级子应用时生效
   */
  prefetch?: string[];
}

export interface MicroInfo {
  activeRule: string;
  entry: Entry;
  extra?: Record<string, any>;
  name: string;
  type?: MicroType;
}

export enum MicroType {
  Route = 'route',
  Component = 'component',
}

export type CollectLogFn = (type: CollectType, options: Record<string, any>) => void;
```