npm package: @gdyfe/micro-app-devtools
Description: <!--  * @Author: Whzcorcd  * @Date: 2021-05-19 10:48:27  * @LastEditors: Whzcorcd  * @LastEditTime: 2021-07-05 16:01:26  * @Description: file content --> # Micro-App-Devtools
Author: Whzcorcd
Latest version: 1.3.0

<!--
 * @Author: Whzcorcd
 * @Date: 2021-05-19 10:48:27
 * @LastEditors: Whzcorcd
 * @LastEditTime: 2021-07-05 16:01:26
 * @Description: file content
-->
# Micro-App-Devtools

基于 qiankun 框架封装的一键式微应用集成开发套件（开发套件依赖 webpack/vue 3.x）

## update

1. 修改微应用实例 instance 的修饰符，完善 instance unmount 流程
2. 微应用生命周期加入 update 钩子
3. 主应用内 loadRegisteredMicroApp 方法增加 mount、unmount、update 方法导出；loadMicroApp 调用时 name 加入随机值使其单次唯一；单例模式作为可选项开放配置

## Install

### 直接引入

将 `dist/index.js` 取出后，使用 `<script>` 标签全局引入

```html
<script type="text/javascript" src="dist/index.js"></script>
<script type="module" src="dist/index.esm.js"></script>
```

### 依赖安装

```bash
npm install @gdyfe/micro-app-devtools --save
yarn add @gdyfe/micro-app-devtools
```

*注意：微应用内该模块 import 声明应该放置在项目主入口的最顶层，以保证 webpack 路径重设能正确触发*

## Usage

### 主应用端

主应用需先注册微应用，然后才可以加载已注册的微应用

#### registeredMicroApps

- 类型：`Map`

- 用途：存储已注册的微应用信息数据

- 解析：依赖 window 对象上名为 `registeredMicroApps` 的键进行数据转储

#### registerMicroApp

- 类型：`Function`

- 参数：`name: string, entry: string`

- 返回值：无

- 用途：注册微应用信息数据

- 解析：参数 name 为微应用唯一标识名称和存储键，之后仅通过 name 查找对应微应用；entry 为当前注册的微应用的入口地址

#### removeMicroApp

- 类型：`Function`

- 参数：`name: string`

- 返回值：无

- 用途：移除对应的已注册的微应用信息数据

#### removeAllMicroApp

- 类型：`Function`

- 参数：无

- 返回值：无

- 用途：移除全部已注册的微应用信息数据

#### loadRegisteredMicroApp

- 类型：`Function`

- 参数：`params: IRegisteredMicroAppParams`

- 返回值：`TMicroAppReturnValues`

- 用途：存储已注册的微应用信息数据

- 解析：

```typescript
export interface IRegisteredMicroAppParams {
  singular?: boolean // 是否以单例模式加载
  name?: string // 已注册的微应用名称
  container?: string // 微应用挂载容器节点
  token?: string // 下发至微应用的 token
  props?: any // 附加参数
  callbacks?: { name: string; fn: Function }[] // 响应微应用 message 的回调数组
}

export type TMicroAppReturnValues = {
  mount: () => Promise<null> // 手动加载微应用
  unmount: () => Promise<null> // 手动卸载微应用
  update: ((customProps: CustomProps) => Promise<any>) | undefined // 手动更新微应用
  dispatch: (name: string, payload: any) => void // 触发微应用 action
  offGlobalStateChange: () => boolean //  qiankun 框架全局 state 变化事件
}
```

参数 `token` 为主应用初始化加载微应用时下发至微应用的 token 值，参数可选；参数 `props` 为主应用初始化加载微应用时下发的自定义附加参数，参数可选

主应用可以使用注册函数返回的 `dispatch` 方法，触发注册函数对应的微应用内方法；每一个微应用对应一个 `dispatch` 方法

微应用内返回的 message 将会触发 `callbacks` 内事先定义的同 name 方法

加载函数可在主应用任意地方调用，微应用加载成功后将会作为主应用的一部分渲染；需反复加载同一个微应用前请手动卸载当前节点的微应用（使用 unmount 方法），且每次加载的微应用会赋予基于 name 的唯一命名

#### prefetchRegisteredMicroApps

- 类型：`Function`

- 参数：`appNames: string[]`

- 返回值：无

- 用途：预加载已注册的微应用，支持多个同时预加载

- 解析：参数 `appNames` 即为需要预加载的微应用的名称的集合

### 微应用端

即微前端子应用，微应用模式下不能使用前端路由，SPA 挂载节点 id 默认为 `#microapp`

微应用端还需要设置 webpack `output` 配置，设置输出格式为 **UMD**，示例：

```javascript
output: {
  library: `${publicPathName}.[chunkhash]`,
  libraryTarget: 'umd', // 把微应用打包成 umd 格式
  jsonpFunction: `webpackJsonp_${publicPathName}`,
}
```

同时如需隔离主应用和子应用样式，微应用内必须关闭 css 提取

```javascript
extract: false
```

#### createMicroApp

- 类型：`Function`

- 参数：`microAppProps: IMicroAppProps`

- 返回值：`{
    bootstrap: () => Promise<void>;
    mount: (props: any) => Promise<void>;
    update: (props: any) => Promise<void>;
    unmount: () => Promise<void>;
}`

- 用途：创建微前端子应用

- 解析：

```typescript
interface ITokenChange {
  token: string
}

interface IActionHandle {
  name: string
  payload: any
}

interface IMicroAppProps {
  instance: App<Element> | null // Vue App 实例，引用传递
  container?: Element | string // 作为微应用时容器
  target?: string // 微应用自身 SPA 挂载节点
  store?: Store<any> | null // Vue Store 实例，引用传递
  onBootstrap?: Function // 微应用 bootstrap 生命周期函数
  onMount?: Function // 微应用 mount 生命周期函数
  onUpdate?: Function // 微应用 update 生命周期函数
  onUnmount?: Function // 微应用 unmount 生命周期函数
  onTokenChange?: (t: ITokenChange) => {} // 微应用 token 更改事件
  onActionHandle?: (p: IActionHandle) => {} // 微应用事件句柄
}
```

`onBootstrap/onMount/onUnmount` 分别对应 qiankun 框架子应用 `bootstrap/mount/unmount` 生命周期

当主应用初始化加载微应用时，会向微应用内注入 token，此时会触发 `onTokenChange` 回调，可以在回调内做存储 token 等相关操作

当主应用触发 `dispatch` 操作后，会向微应用内提交 action，`onActionHandle` 用于接收到新的 action 时执行逻辑；单一 action 由 `name` 和 `payload` 两部分组成，可以使用 switch 语句或者策略模式对不同的 action 做成不同响应逻辑

开发套件实例会在 instance.config.globalProperties 上挂载 `$send` 方法（即`instance.config.globalProperties.$send `），此方法用于主动向主应用发送 message，将会按 name 触发主应用事先定义的 对应 `callbacks`