Skip to content

Commit

Permalink
fix: fix some doc mistakes
Browse files Browse the repository at this point in the history
  • Loading branch information
danpeen committed Oct 11, 2023
1 parent 1233f4f commit 67b8ac0
Show file tree
Hide file tree
Showing 3 changed files with 110 additions and 68 deletions.
98 changes: 63 additions & 35 deletions website/docs/api/loadApp.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,26 +3,32 @@ title: Garfish.loadApp
slug: /api/loadApp
order: 4
---
import Highlight from '@site/src/components/Highlight';

import Highlight from '@site/src/components/Highlight';

用于手动挂载子应用,可动态控制子应用的渲染和销毁。
> 通过 `Garfish.run()` API 注册的子应用会自动根据路由进行应激活子应用的匹配逻辑,属于路由驱动式的应用挂载和销毁模式。如果你的场景下希望手动控制应用的加载和销毁,你可以使用 `Garfish.loadApp()` 的方式加载应用,它是一种更加灵活的微前端应用加载模式。

> Garfish 支持路由驱动式的应用挂载和销毁模式,
> 如果你的应用配置了 `activeWhen`, Garfish 则将自动监听路由变化并在路由命中时加载对应的子应用。这种模式属于路由驱动式的应用加载模式。如果你希望手动控制应用的加载和销毁,我们提供了 `Garfish.loadApp()` API 以供用户手动加载和销毁应用,这是一种更加灵活的子应用加载模式。
:::info

1. 基于路由匹配的应用加载模式会通过子应用的 `activeWhen` 参数在在路由变化后自动判断当前应加载的子应用;
2. 在手动加载模式下(Garfish.loadApp),Garfish 不会根据路径匹配而是完全由开发者控制应用加载和销毁,此时应用加载不会受到 `activeWhen` 参数的影响;
:::
:::

## 类型

```ts
loadApp(appName: string, options?: Omit<interfaces.AppInfo, 'name'>): Promise<interfaces.App | null>;
```

## 默认值

-

## 示例

import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';

Expand Down Expand Up @@ -106,25 +112,29 @@ export default App = () => {
</TabItem>
</Tabs> -->


## 参数

### name
- Type: <Highlight> string </Highlight>
- 要加载的子应用名称,必选。
- 各子应用的名称应保持唯一,这是子应用的唯一标识;

- Type: <Highlight> string </Highlight>
- 要加载的子应用名称,必选。
- 各子应用的名称应保持唯一,这是子应用的唯一标识;

:::tip

1. 请确保当前要加载的子应用信息已注册。Garfish 会从已注册的 app 信息中查找同名 app,若应用信息未注册将导致应用加载失败。
2. 应用信息注册可通过 `Garfish.run()``Garfish.registerApp()``Garfish.setOptions()` 三种方式注册;
:::
:::

### options?

- Type: <Highlight> Omit <interfaces.AppInfo, 'name'> </Highlight>

- `options` 参数含义本质上与 [registerApp](/api/registerApp#参数) 中同名参数保持一致,可选。
- 可移步 [registerApp](/api/registerApp#参数) 查看具体参数说明;这里仅针对注意事项进行说明。

:::info

> `options` 的作用?
这里提供 `options` 是允许用户在手动加载 App 时自定义当前应用的信息参数,若之前已注册过子应用,则会将已配置信息和这里的 `options` 参数进行 deepMerge,提供用户运行时更新 App 应用信息参数的能力;
Expand All @@ -141,62 +151,68 @@ export default App = () => {
## 返回值

```ts
import Garfish from "garfish";
import type { interfaces } from "garfish";
import Garfish from 'garfish';
import type { interfaces } from 'garfish';

let app: interfaces.App;
app = await Garfish.loadApp('vue-app', {
cache: true,
basename,
domGetter: '#container',
entry: 'http://localhost:8092',
cache: true,
basename,
domGetter: '#container',
entry: 'http://localhost:8092',
});
```

> loadApp 的返回值为子应用的 App 实例对象,实例对象上存在一些方法和属性,提供给开发者用于手动进行 App 的挂载、销毁及判断 App 当前应用状态等信息;
### 实例属性
- <Highlight> name: string </Highlight>

应用名称,string。
- <Highlight> name: string </Highlight>

应用名称,string。

- <Highlight> mounted: boolean </Highlight>
- <Highlight> mounted: boolean </Highlight>

应用是否已挂载,boolean。 `true` 表示已挂载,`false` 表示未挂载。
应用是否已挂载,boolean。 `true` 表示已挂载,`false` 表示未挂载。

- <Highlight> display: boolean </Highlight>
- <Highlight> display: boolean </Highlight>

应用是否被隐藏,boolean。 `true` 表示显示状态,未隐藏,`false` 表示隐藏态。
应用是否被隐藏,boolean。 `true` 表示显示状态,未隐藏,`false` 表示隐藏态。

- <Highlight> strictIsolation: boolean </Highlight>
- <Highlight> strictIsolation: boolean </Highlight>

是否开启严格隔离。`true` 表示已开启,`false` 表示未开启。
是否开启严格隔离。`true` 表示已开启,`false` 表示未开启。

- <Highlight> isHtmlMode: boolean </Highlight>
- <Highlight> isHtmlMode: boolean </Highlight>

是否是 `html` 入口模式。
是否是 `html` 入口模式。

- <Highlight> appContainer: HTMLElement </Highlight>
- <Highlight> appContainer: HTMLElement </Highlight>

应用容器
应用容器

- <Highlight> appInfo: AppInfo </Highlight>
- <Highlight> appInfo: AppInfo </Highlight>

应用配置信息
应用配置信息

- <Highlight> hooks: interfaces.AppHooks </Highlight>
- <Highlight> hooks: interfaces.AppHooks </Highlight>
应用生命周期钩子函数

### 实例方法

- app.mount()

- Type

```ts
mount(): Promise<boolean>
```

- 示例

```ts
import Garfish from "garfish";
import type { interfaces } from "garfish";
import Garfish from 'garfish';
import type { interfaces } from 'garfish';
const app = await Garfish.loadApp('vue-app', {
cache: true,
Expand All @@ -206,6 +222,7 @@ app = await Garfish.loadApp('vue-app', {
});
await app.mount();
```

- 触发子应用的 <Highlight> 渲染</Highlight> 流程。若应用<span style={{color: '#9b67f6'}}> 已挂载 </span>、或<span style={{color: '#9b67f6'}}> 正在挂载中 </span>、或<span style={{color: '#9b67f6'}}> 正在卸载中 </span>将不会触发渲染流程;
- 在子应用渲染前将会触发 `beforeMount` 钩子函数,渲染完成将触发 `afterMount` 钩子函数并将当前挂载的应用 push`Garfish.activeApps`。若渲染过程中出现异常将触发 `errorMountApp`钩子函数;
- 在此过程中将执行 `provider` 提供的子应用 `render` 函数,若 `provider` 函数未找到将会抛出错误。[尝试解决](/issues/#provider-is-null)
Expand All @@ -216,25 +233,31 @@ app = await Garfish.loadApp('vue-app', {
:::

- app.unmount()

```ts
unmount(): boolean;
```

- 触发子应用的 <Highlight> 销毁</Highlight> 流程。若应用<span style={{color: '#9b67f6'}}> 正在卸载中 </span>,将不会重复卸载;
- 在子应用渲染前将会触发 `beforeUnmount` 钩子函数,渲染完成将触发 `afterUnmount` ,若销毁过程中出现异常将触发 `errorUnmountApp` 钩子函数;
- 应用卸载过程中会执行 `provider` 内部提供的 `destroy` 函数。卸载完成后,子应用的渲染容器将被移除、子应用的执行上下文也将被销毁,渲染过程中产生的副作用也都将会被清除,同时将子应用从
`Garfish.activeApps` 里移除,`mounted``display` 状态置为 false
`Garfish.activeApps` 里移除,`mounted``display` 状态置为 false
- [unmount 过程中都做了哪些事情](/guide/lifecycle#unmount)

- app.show()

- Type

```ts
show(): Promise<boolean>
```

- 触发子应用的 <Highlight> 显示</Highlight> 流程;
- 示例

```ts
import Garfish from "garfish";
import type { interfaces } from "garfish";
import Garfish from 'garfish';
import type { interfaces } from 'garfish';
const app = await Garfish.loadApp('vue-app', {
cache: true,
Expand All @@ -245,23 +268,28 @@ app = await Garfish.loadApp('vue-app', {
// 若已经渲染触发 show,只有首次渲染触发 mount,后面渲染都可以触发 show 提供性能
app.mounted ? app.show() : await app.mount();
```

- 触发子应用的 <Highlight> 显示</Highlight> 流程。若应用<span style={{color: '#9b67f6'}}> 已显示 </span>、或<span style={{color: '#9b67f6'}}> 未挂载 </span> 将不会触发应用渲染流程;

- 在子应用显示前将会触发 `beforeMount` 钩子函数,显示完成将触发 `afterMount` 钩子函数并将当前挂载的应用 push`Garfish.activeApps`
- 在此过程中将执行 `provider` 提供的子应用 render 函数,若 `provider` 函数未找到将会抛出错误。[尝试解决](/issues/#provider-is-null)
- [show 过程中都做了哪些事情](/guide/lifecycle#show)

:::info 请注意:

1. `app.show()` 用于触发子应用的显示流程,此过程并不是 css 中样式的显示或隐藏,show() 方法会触发子应用的 `render` 函数,若 `render` 函数中存在副作用也会再次执行;
2. `app.show()` 在应用渲染的过程中将会执行 `provider` 中提供的 `render` 函数,但与 `app.mount()` 不同的是,`app.show()` 不会创建新的执行上下文;
3. 在基于路由驱动子应用加载模式下,若已启用缓存(`cache: true`),则会默认使用 show() 触发子应用的渲染。若未开启缓存模式,则会使用 `app.mount()` 渲染子应用。非路由驱动模式下,由开发者控制子应用的渲染和销毁;
:::
:::

- app.hide()

- Type

```ts
hide(): boolean;
```

- 触发子应用的 <Highlight> 隐藏</Highlight> 流程。若应用<span style={{color: '#9b67f6'}}> 未显示 </span>、或<span style={{color: '#9b67f6'}}> 未挂载 </span> 将不会触发应用隐藏流程;

- 在子应用隐藏前将会触发 `beforeUnmount` 钩子函数,隐藏完成将触发 `afterUnmount` 钩子函数并将当前隐藏的应用从 `Garfish.activeApps` 中移除;
Expand Down
2 changes: 1 addition & 1 deletion website/docs/guide/concept/sandbox.md
Original file line number Diff line number Diff line change
Expand Up @@ -335,7 +335,7 @@ if ($CONFIG.a) {
最初的版本我们通过重写 HTMLElement.prototype.appendChild,把 append 到 body 的样式放到子应用渲染的根节点里。由于劫持的是原型,这个方案无法支持多实例,如果有多个子应用同时运行,没办法区分是由哪个子应用添加的。
2. 劫持实例的 appendChild
所以我们想到的是去劫持所有的 dom 节点,通过重写获取 dom 节点的方法,如 `document.querySelector``ocument.getElementByID`, 把返回的 `dom` 节点通过 `proxy` 进行包装,这样就能劫持 dom 实例的 appendChild,就可以区分是来自于哪个子应用。但是这个方案经过实践,出现的两个比较棘手的问题:
所以我们想到的是去劫持所有的 dom 节点,通过重写获取 dom 节点的方法,如 `document.querySelector``document.getElementByID`, 把返回的 `dom` 节点通过 `proxy` 进行包装,这样就能劫持 dom 实例的 appendChild,就可以区分是来自于哪个子应用。但是这个方案经过实践,出现的两个比较棘手的问题:
- 封装后的 dom 节点在传参的时候会报错,如
Expand Down
Loading

0 comments on commit 67b8ac0

Please sign in to comment.