🎨 upgrade prettier and format docs (#1377)
This commit is contained in:
parent
90906feaea
commit
8e521521b9
|
|
@ -33,7 +33,7 @@ loadMicroApp({
|
|||
entry: '//localhost:7100',
|
||||
container: '#container',
|
||||
props: {
|
||||
slogan: 'Hello Qiankun'
|
||||
slogan: 'Hello Qiankun',
|
||||
},
|
||||
});
|
||||
```
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ loadMicroApp({
|
|||
entry: '//localhost:7100',
|
||||
container: '#container',
|
||||
props: {
|
||||
slogan: 'Hello Qiankun'
|
||||
slogan: 'Hello Qiankun',
|
||||
},
|
||||
});
|
||||
```
|
||||
|
|
|
|||
|
|
@ -32,39 +32,39 @@ By linking the micro-application to some url rules, the function of automaticall
|
|||
|
||||
- activeRule - - `string | (location: Location) => boolean | Array<string | (location: Location) => boolean> ` - required,activation rules for micro-apps.
|
||||
|
||||
* Support direct configuration of string or string array, such as `activeRule: '/app1'` or `activeRule: ['/app1', '/app2']`, when configured as a string, it will directly follow the path part in the url Do a prefix match. A successful match indicates that the current application will be activated.
|
||||
* Support to configure an active function or a group of active functions. The function will pass in the current location as a parameter. When the function returns true, it indicates that the current micro application will be activated. Such as `location => location.pathname.startsWith ('/app1')`.
|
||||
- Support direct configuration of string or string array, such as `activeRule: '/app1'` or `activeRule: ['/app1', '/app2']`, when configured as a string, it will directly follow the path part in the url Do a prefix match. A successful match indicates that the current application will be activated.
|
||||
- Support to configure an active function or a group of active functions. The function will pass in the current location as a parameter. When the function returns true, it indicates that the current micro application will be activated. Such as `location => location.pathname.startsWith ('/app1')`.
|
||||
|
||||
Example rules:
|
||||
|
||||
`'/app1'`
|
||||
|
||||
* ✅ https://app.com/app1
|
||||
- ✅ https://app.com/app1
|
||||
|
||||
* ✅ https://app.com/app1/anything/everything
|
||||
- ✅ https://app.com/app1/anything/everything
|
||||
|
||||
* 🚫 https://app.com/app2
|
||||
- 🚫 https://app.com/app2
|
||||
|
||||
`'/users/:userId/profile'`
|
||||
|
||||
* ✅ https://app.com/users/123/profile
|
||||
* ✅ https://app.com/users/123/profile/sub-profile/
|
||||
* 🚫 https://app.com/users//profile/sub-profile/
|
||||
* 🚫 https://app.com/users/profile/sub-profile/
|
||||
- ✅ https://app.com/users/123/profile
|
||||
- ✅ https://app.com/users/123/profile/sub-profile/
|
||||
- 🚫 https://app.com/users//profile/sub-profile/
|
||||
- 🚫 https://app.com/users/profile/sub-profile/
|
||||
|
||||
`'/pathname/#/hash'`
|
||||
|
||||
* ✅ https://app.com/pathname/#/hash
|
||||
* ✅ https://app.com/pathname/#/hash/route/nested
|
||||
* 🚫 https://app.com/pathname#/hash/route/nested
|
||||
* 🚫 https://app.com/pathname#/another-hash
|
||||
- ✅ https://app.com/pathname/#/hash
|
||||
- ✅ https://app.com/pathname/#/hash/route/nested
|
||||
- 🚫 https://app.com/pathname#/hash/route/nested
|
||||
- 🚫 https://app.com/pathname#/another-hash
|
||||
|
||||
`['/pathname/#/hash', '/app1']`
|
||||
|
||||
* ✅ https://app.com/pathname/#/hash/route/nested
|
||||
* ✅ https://app.com/app1/anything/everything
|
||||
* 🚫 https://app.com/pathname/app1
|
||||
* 🚫 https://app.com/app2
|
||||
- ✅ https://app.com/pathname/#/hash/route/nested
|
||||
- ✅ https://app.com/app1/anything/everything
|
||||
- 🚫 https://app.com/pathname/app1
|
||||
- 🚫 https://app.com/app2
|
||||
|
||||
This function is called when the browser url changes, and `activeRule` returns `true` to indicate that the subapplication needs to be activated.
|
||||
|
||||
|
|
@ -102,14 +102,12 @@ By linking the micro-application to some url rules, the function of automaticall
|
|||
activeRule: '/react',
|
||||
props: {
|
||||
name: 'kuitos',
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
],
|
||||
{
|
||||
beforeLoad: app => console.log('before load', app.name),
|
||||
beforeMount: [
|
||||
app => console.log('before mount', app.name),
|
||||
],
|
||||
beforeLoad: (app) => console.log('before load', app.name),
|
||||
beforeMount: [(app) => console.log('before mount', app.name)],
|
||||
},
|
||||
);
|
||||
```
|
||||
|
|
@ -151,8 +149,7 @@ By linking the micro-application to some url rules, the function of automaticall
|
|||
}
|
||||
```
|
||||
|
||||
notice:
|
||||
@keyframes, @font-face, @import, @page are not supported (i.e. will not be rewritten)
|
||||
notice: @keyframes, @font-face, @import, @page are not supported (i.e. will not be rewritten)
|
||||
|
||||
- singular - `boolean | ((app: RegistrableApp<any>) => Promise<boolean>);` - Optional, whether it is a singleton scenario, singleton means just rendered one micro app at one time. default is `true`.
|
||||
|
||||
|
|
@ -224,16 +221,18 @@ A criterion for judging whether the business is closely related: <strong>Look at
|
|||
|
||||
### `loadMicroApp(app, configuration?)`
|
||||
|
||||
* Parameters
|
||||
* app - `LoadableApp` - Required, basic information of micro application
|
||||
* name - `string` - Required, the name of the micro application must be unique among the micro applications.
|
||||
* entry - `string | { scripts?: string[]; styles?: string[]; html?: string }` - Required, The entry of the micro application(The detailed description is the same as above).
|
||||
* container - `string | HTMLElement` - Required, selector or Element instance of the container node of the micro application. Such as `container: '#root'` or `container: document.querySelector('#root')`.
|
||||
* props - `object` - Optional, the data that needs to be passed to the micro-application during initialization.
|
||||
- Parameters
|
||||
|
||||
* configuration - `Configuration` - Optional, configuration information of the micro application
|
||||
- app - `LoadableApp` - Required, basic information of micro application
|
||||
|
||||
* sandbox - `boolean` | `{ strictStyleIsolation?: boolean, experimentalStyleIsolation?: boolean }` - optional, whether to open the js sandbox, default is `true`.
|
||||
- name - `string` - Required, the name of the micro application must be unique among the micro applications.
|
||||
- entry - `string | { scripts?: string[]; styles?: string[]; html?: string }` - Required, The entry of the micro application(The detailed description is the same as above).
|
||||
- container - `string | HTMLElement` - Required, selector or Element instance of the container node of the micro application. Such as `container: '#root'` or `container: document.querySelector('#root')`.
|
||||
- props - `object` - Optional, the data that needs to be passed to the micro-application during initialization.
|
||||
|
||||
- configuration - `Configuration` - Optional, configuration information of the micro application
|
||||
|
||||
- sandbox - `boolean` | `{ strictStyleIsolation?: boolean, experimentalStyleIsolation?: boolean }` - optional, whether to open the js sandbox, default is `true`.
|
||||
|
||||
When configured as `{strictStyleIsolation: true}`, qiankun will convert the container dom of each application to a [shadow dom](https://developer.mozilla.org/en-US/docs/Web/Web_Components/Using_shadow_DOM), to ensure that the style of the application will not leak to the global.
|
||||
|
||||
|
|
@ -250,42 +249,30 @@ A criterion for judging whether the business is closely related: <strong>Look at
|
|||
}
|
||||
```
|
||||
|
||||
notice:
|
||||
@keyframes, @font-face, @import, @page are not supported (i.e. will not be rewritten)
|
||||
notice: @keyframes, @font-face, @import, @page are not supported (i.e. will not be rewritten)
|
||||
|
||||
* singular - `boolean | ((app: RegistrableApp<any>) => Promise<boolean>);` - Optional, whether it is a singleton scenario, singleton means just rendered one micro app at one time. Default is `false`.
|
||||
- singular - `boolean | ((app: RegistrableApp<any>) => Promise<boolean>);` - Optional, whether it is a singleton scenario, singleton means just rendered one micro app at one time. Default is `false`.
|
||||
|
||||
* fetch - `Function` - Optional, custom fetch method.
|
||||
- fetch - `Function` - Optional, custom fetch method.
|
||||
|
||||
* getPublicPath - `(url: string) => string` - Optional,The parameter is the entry value of the micro application.
|
||||
- getPublicPath - `(url: string) => string` - Optional,The parameter is the entry value of the micro application.
|
||||
|
||||
* getTemplate - `(tpl: string) => string` - Optional
|
||||
- getTemplate - `(tpl: string) => string` - Optional
|
||||
|
||||
* excludeAssetFilter - `(assetUrl: string) => boolean` - optional,some special dynamic loaded micro app resources should not be handled by qiankun hijacking
|
||||
- excludeAssetFilter - `(assetUrl: string) => boolean` - optional,some special dynamic loaded micro app resources should not be handled by qiankun hijacking
|
||||
|
||||
* 返回值 - `MicroApp` - Micro application examples
|
||||
* mount(): Promise<null>;
|
||||
* unmount(): Promise<null>;
|
||||
* update(customProps: object): Promise<any>;
|
||||
* getStatus():
|
||||
| "NOT_LOADED"
|
||||
| "LOADING_SOURCE_CODE"
|
||||
| "NOT_BOOTSTRAPPED"
|
||||
| "BOOTSTRAPPING"
|
||||
| "NOT_MOUNTED"
|
||||
| "MOUNTING"
|
||||
| "MOUNTED"
|
||||
| "UPDATING"
|
||||
| "UNMOUNTING"
|
||||
| "UNLOADING"
|
||||
| "SKIP_BECAUSE_BROKEN"
|
||||
| "LOAD_ERROR";
|
||||
* loadPromise: Promise<null>;
|
||||
* bootstrapPromise: Promise<null>;
|
||||
* mountPromise: Promise<null>;
|
||||
* unmountPromise: Promise<null>;
|
||||
- 返回值 - `MicroApp` - Micro application examples
|
||||
|
||||
* Usage
|
||||
- mount(): Promise<null>;
|
||||
- unmount(): Promise<null>;
|
||||
- update(customProps: object): Promise<any>;
|
||||
- getStatus(): | "NOT_LOADED" | "LOADING_SOURCE_CODE" | "NOT_BOOTSTRAPPED" | "BOOTSTRAPPING" | "NOT_MOUNTED" | "MOUNTING" | "MOUNTED" | "UPDATING" | "UNMOUNTING" | "UNLOADING" | "SKIP_BECAUSE_BROKEN" | "LOAD_ERROR";
|
||||
- loadPromise: Promise<null>;
|
||||
- bootstrapPromise: Promise<null>;
|
||||
- mountPromise: Promise<null>;
|
||||
- unmountPromise: Promise<null>;
|
||||
|
||||
- Usage
|
||||
|
||||
Load a micro application manually.
|
||||
|
||||
|
|
@ -302,21 +289,23 @@ A criterion for judging whether the business is closely related: <strong>Look at
|
|||
}
|
||||
```
|
||||
|
||||
* Sample
|
||||
- Sample
|
||||
|
||||
```jsx
|
||||
import { loadMicroApp } from 'qiankun';
|
||||
import React from 'react';
|
||||
|
||||
class App extends React.Component {
|
||||
|
||||
containerRef = React.createRef();
|
||||
microApp = null;
|
||||
|
||||
componentDidMount() {
|
||||
this.microApp = loadMicroApp(
|
||||
{ name: 'app1', entry: '//localhost:1234', container: this.containerRef.current, props: { brand: 'qiankun' } },
|
||||
);
|
||||
this.microApp = loadMicroApp({
|
||||
name: 'app1',
|
||||
entry: '//localhost:1234',
|
||||
container: this.containerRef.current,
|
||||
props: { brand: 'qiankun' },
|
||||
});
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
|
|
@ -336,10 +325,12 @@ A criterion for judging whether the business is closely related: <strong>Look at
|
|||
### `prefetchApps(apps, importEntryOpts?)`
|
||||
|
||||
- Parameters
|
||||
|
||||
- apps - `AppMetadata[]` - Required - list of preloaded apps
|
||||
- importEntryOpts - Optional - Load configuration
|
||||
|
||||
- Type
|
||||
|
||||
- `AppMetadata`
|
||||
- name - `string` - Required - Application name
|
||||
- entry - `string | { scripts?: string[]; styles?: string[]; html?: string }` - Required,The entry address of the microapp
|
||||
|
|
@ -353,7 +344,10 @@ A criterion for judging whether the business is closely related: <strong>Look at
|
|||
```ts
|
||||
import { prefetchApps } from 'qiankun';
|
||||
|
||||
prefetchApps([ { name: 'app1', entry: '//locahost:7001' }, { name: 'app2', entry: '//locahost:7002' } ])
|
||||
prefetchApps([
|
||||
{ name: 'app1', entry: '//locahost:7001' },
|
||||
{ name: 'app2', entry: '//locahost:7002' },
|
||||
]);
|
||||
```
|
||||
|
||||
## [addErrorHandler/removeErrorHandler](https://single-spa.js.org/docs/api#adderrorhandler)
|
||||
|
|
@ -373,7 +367,7 @@ A criterion for judging whether the business is closely related: <strong>Look at
|
|||
```ts
|
||||
import { addGlobalUncaughtErrorHandler } from 'qiankun';
|
||||
|
||||
addGlobalUncaughtErrorHandler(event => console.log(event));
|
||||
addGlobalUncaughtErrorHandler((event) => console.log(event));
|
||||
```
|
||||
|
||||
## `removeGlobalUncaughtErrorHandler(handler)`
|
||||
|
|
@ -417,6 +411,7 @@ A criterion for judging whether the business is closely related: <strong>Look at
|
|||
- Sample
|
||||
|
||||
Master:
|
||||
|
||||
```ts
|
||||
import { initGlobalState, MicroAppStateActions } from 'qiankun';
|
||||
|
||||
|
|
@ -432,10 +427,10 @@ A criterion for judging whether the business is closely related: <strong>Look at
|
|||
```
|
||||
|
||||
Slave:
|
||||
|
||||
```ts
|
||||
// get actions from mount
|
||||
export function mount(props) {
|
||||
|
||||
props.onGlobalStateChange((state, prev) => {
|
||||
// state: new state; prev old state
|
||||
console.log(state, prev);
|
||||
|
|
|
|||
|
|
@ -32,39 +32,39 @@ toc: menu
|
|||
|
||||
- activeRule - `string | (location: Location) => boolean | Array<string | (location: Location) => boolean> ` - 必选,微应用的激活规则。
|
||||
|
||||
* 支持直接配置字符串或字符串数组,如 `activeRule: '/app1'` 或 `activeRule: ['/app1', '/app2']`,当配置为字符串时会直接跟 url 中的路径部分做前缀匹配,匹配成功表明当前应用会被激活。
|
||||
* 支持配置一个 active function 函数或一组 active function。函数会传入当前 location 作为参数,函数返回 true 时表明当前微应用会被激活。如 `location => location.pathname.startsWith('/app1')`。
|
||||
- 支持直接配置字符串或字符串数组,如 `activeRule: '/app1'` 或 `activeRule: ['/app1', '/app2']`,当配置为字符串时会直接跟 url 中的路径部分做前缀匹配,匹配成功表明当前应用会被激活。
|
||||
- 支持配置一个 active function 函数或一组 active function。函数会传入当前 location 作为参数,函数返回 true 时表明当前微应用会被激活。如 `location => location.pathname.startsWith('/app1')`。
|
||||
|
||||
规则示例:
|
||||
|
||||
`'/app1'`
|
||||
|
||||
* ✅ https://app.com/app1
|
||||
- ✅ https://app.com/app1
|
||||
|
||||
* ✅ https://app.com/app1/anything/everything
|
||||
- ✅ https://app.com/app1/anything/everything
|
||||
|
||||
* 🚫 https://app.com/app2
|
||||
- 🚫 https://app.com/app2
|
||||
|
||||
`'/users/:userId/profile'`
|
||||
|
||||
* ✅ https://app.com/users/123/profile
|
||||
* ✅ https://app.com/users/123/profile/sub-profile/
|
||||
* 🚫 https://app.com/users//profile/sub-profile/
|
||||
* 🚫 https://app.com/users/profile/sub-profile/
|
||||
- ✅ https://app.com/users/123/profile
|
||||
- ✅ https://app.com/users/123/profile/sub-profile/
|
||||
- 🚫 https://app.com/users//profile/sub-profile/
|
||||
- 🚫 https://app.com/users/profile/sub-profile/
|
||||
|
||||
`'/pathname/#/hash'`
|
||||
|
||||
* ✅ https://app.com/pathname/#/hash
|
||||
* ✅ https://app.com/pathname/#/hash/route/nested
|
||||
* 🚫 https://app.com/pathname#/hash/route/nested
|
||||
* 🚫 https://app.com/pathname#/another-hash
|
||||
- ✅ https://app.com/pathname/#/hash
|
||||
- ✅ https://app.com/pathname/#/hash/route/nested
|
||||
- 🚫 https://app.com/pathname#/hash/route/nested
|
||||
- 🚫 https://app.com/pathname#/another-hash
|
||||
|
||||
`['/pathname/#/hash', '/app1']`
|
||||
|
||||
* ✅ https://app.com/pathname/#/hash/route/nested
|
||||
* ✅ https://app.com/app1/anything/everything
|
||||
* 🚫 https://app.com/pathname/app1
|
||||
* 🚫 https://app.com/app2
|
||||
- ✅ https://app.com/pathname/#/hash/route/nested
|
||||
- ✅ https://app.com/app1/anything/everything
|
||||
- 🚫 https://app.com/pathname/app1
|
||||
- 🚫 https://app.com/app2
|
||||
|
||||
浏览器 url 发生变化会调用 activeRule 里的规则,`activeRule` 任意一个返回 `true` 时表明该微应用需要被激活。
|
||||
|
||||
|
|
@ -102,14 +102,12 @@ toc: menu
|
|||
activeRule: '/react',
|
||||
props: {
|
||||
name: 'kuitos',
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
],
|
||||
{
|
||||
beforeLoad: app => console.log('before load', app.name),
|
||||
beforeMount: [
|
||||
app => console.log('before mount', app.name),
|
||||
],
|
||||
beforeLoad: (app) => console.log('before load', app.name),
|
||||
beforeMount: [(app) => console.log('before mount', app.name)],
|
||||
},
|
||||
);
|
||||
```
|
||||
|
|
@ -155,8 +153,7 @@ toc: menu
|
|||
}
|
||||
```
|
||||
|
||||
注意:
|
||||
@keyframes, @font-face, @import, @page 将不被支持 (i.e. 不会被改写)
|
||||
注意: @keyframes, @font-face, @import, @page 将不被支持 (i.e. 不会被改写)
|
||||
|
||||
- singular - `boolean | ((app: RegistrableApp<any>) => Promise<boolean>);` - 可选,是否为单实例场景,单实例指的是同一时间只会渲染一个微应用。默认为 `true`。
|
||||
|
||||
|
|
@ -228,16 +225,18 @@ toc: menu
|
|||
|
||||
### `loadMicroApp(app, configuration?)`
|
||||
|
||||
* 参数
|
||||
* app - `LoadableApp` - 必选,微应用的基础信息
|
||||
* name - `string` - 必选,微应用的名称,微应用之间必须确保唯一。
|
||||
* entry - `string | { scripts?: string[]; styles?: string[]; html?: string }` - 必选,微应用的入口(详细说明同上)。
|
||||
* container - `string | HTMLElement` - 必选,微应用的容器节点的选择器或者 Element 实例。如`container: '#root'` 或 `container: document.querySelector('#root')`。
|
||||
* props - `object` - 可选,初始化时需要传递给微应用的数据。
|
||||
- 参数
|
||||
|
||||
* configuration - `Configuration` - 可选,微应用的配置信息
|
||||
- app - `LoadableApp` - 必选,微应用的基础信息
|
||||
|
||||
* sandbox - `boolean` | `{ strictStyleIsolation?: boolean, experimentalStyleIsolation?: boolean }` - 可选,是否开启沙箱,默认为 `true`。
|
||||
- name - `string` - 必选,微应用的名称,微应用之间必须确保唯一。
|
||||
- entry - `string | { scripts?: string[]; styles?: string[]; html?: string }` - 必选,微应用的入口(详细说明同上)。
|
||||
- container - `string | HTMLElement` - 必选,微应用的容器节点的选择器或者 Element 实例。如`container: '#root'` 或 `container: document.querySelector('#root')`。
|
||||
- props - `object` - 可选,初始化时需要传递给微应用的数据。
|
||||
|
||||
- configuration - `Configuration` - 可选,微应用的配置信息
|
||||
|
||||
- sandbox - `boolean` | `{ strictStyleIsolation?: boolean, experimentalStyleIsolation?: boolean }` - 可选,是否开启沙箱,默认为 `true`。
|
||||
|
||||
默认情况下沙箱可以确保单实例场景子应用之间的样式隔离,但是无法确保主应用跟子应用、或者多实例场景的子应用样式隔离。当配置为 `{ strictStyleIsolation: true }` 时表示开启严格的样式隔离模式。这种模式下 qiankun 会为每个微应用的容器包裹上一个 [shadow dom](https://developer.mozilla.org/zh-CN/docs/Web/Web_Components/Using_shadow_DOM) 节点,从而确保微应用的样式不会对全局造成影响。
|
||||
|
||||
|
|
@ -258,42 +257,30 @@ toc: menu
|
|||
}
|
||||
```
|
||||
|
||||
注意事项:
|
||||
目前 @keyframes, @font-face, @import, @page 等规则不会支持 (i.e. 不会被改写)
|
||||
注意事项: 目前 @keyframes, @font-face, @import, @page 等规则不会支持 (i.e. 不会被改写)
|
||||
|
||||
* singular - `boolean | ((app: RegistrableApp<any>) => Promise<boolean>);` - 可选,是否为单实例场景,单实例指的是同一时间只会渲染一个微应用。默认为 `false`。
|
||||
- singular - `boolean | ((app: RegistrableApp<any>) => Promise<boolean>);` - 可选,是否为单实例场景,单实例指的是同一时间只会渲染一个微应用。默认为 `false`。
|
||||
|
||||
* fetch - `Function` - 可选,自定义的 fetch 方法。
|
||||
- fetch - `Function` - 可选,自定义的 fetch 方法。
|
||||
|
||||
* getPublicPath - `(entry: Entry) => string` - 可选,参数是微应用的 entry 值。
|
||||
- getPublicPath - `(entry: Entry) => string` - 可选,参数是微应用的 entry 值。
|
||||
|
||||
* getTemplate - `(tpl: string) => string` - 可选
|
||||
- getTemplate - `(tpl: string) => string` - 可选
|
||||
|
||||
* excludeAssetFilter - `(assetUrl: string) => boolean` - 可选,指定部分特殊的动态加载的微应用资源(css/js) 不被qiankun 劫持处理
|
||||
- excludeAssetFilter - `(assetUrl: string) => boolean` - 可选,指定部分特殊的动态加载的微应用资源(css/js) 不被 qiankun 劫持处理
|
||||
|
||||
* 返回值 - `MicroApp` - 微应用实例
|
||||
* mount(): Promise<null>;
|
||||
* unmount(): Promise<null>;
|
||||
* update(customProps: object): Promise<any>;
|
||||
* getStatus():
|
||||
| "NOT_LOADED"
|
||||
| "LOADING_SOURCE_CODE"
|
||||
| "NOT_BOOTSTRAPPED"
|
||||
| "BOOTSTRAPPING"
|
||||
| "NOT_MOUNTED"
|
||||
| "MOUNTING"
|
||||
| "MOUNTED"
|
||||
| "UPDATING"
|
||||
| "UNMOUNTING"
|
||||
| "UNLOADING"
|
||||
| "SKIP_BECAUSE_BROKEN"
|
||||
| "LOAD_ERROR";
|
||||
* loadPromise: Promise<null>;
|
||||
* bootstrapPromise: Promise<null>;
|
||||
* mountPromise: Promise<null>;
|
||||
* unmountPromise: Promise<null>;
|
||||
- 返回值 - `MicroApp` - 微应用实例
|
||||
|
||||
* 用法
|
||||
- mount(): Promise<null>;
|
||||
- unmount(): Promise<null>;
|
||||
- update(customProps: object): Promise<any>;
|
||||
- getStatus(): | "NOT_LOADED" | "LOADING_SOURCE_CODE" | "NOT_BOOTSTRAPPED" | "BOOTSTRAPPING" | "NOT_MOUNTED" | "MOUNTING" | "MOUNTED" | "UPDATING" | "UNMOUNTING" | "UNLOADING" | "SKIP_BECAUSE_BROKEN" | "LOAD_ERROR";
|
||||
- loadPromise: Promise<null>;
|
||||
- bootstrapPromise: Promise<null>;
|
||||
- mountPromise: Promise<null>;
|
||||
- unmountPromise: Promise<null>;
|
||||
|
||||
- 用法
|
||||
|
||||
手动加载一个微应用。
|
||||
|
||||
|
|
@ -310,21 +297,23 @@ toc: menu
|
|||
}
|
||||
```
|
||||
|
||||
* 示例
|
||||
- 示例
|
||||
|
||||
```jsx
|
||||
import { loadMicroApp } from 'qiankun';
|
||||
import React from 'react';
|
||||
|
||||
class App extends React.Component {
|
||||
|
||||
containerRef = React.createRef();
|
||||
microApp = null;
|
||||
|
||||
componentDidMount() {
|
||||
this.microApp = loadMicroApp(
|
||||
{ name: 'app1', entry: '//localhost:1234', container: this.containerRef.current, props: { brand: 'qiankun' } },
|
||||
);
|
||||
this.microApp = loadMicroApp({
|
||||
name: 'app1',
|
||||
entry: '//localhost:1234',
|
||||
container: this.containerRef.current,
|
||||
props: { brand: 'qiankun' },
|
||||
});
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
|
|
@ -344,10 +333,12 @@ toc: menu
|
|||
### `prefetchApps(apps, importEntryOpts?)`
|
||||
|
||||
- 参数
|
||||
|
||||
- apps - `AppMetadata[]` - 必选 - 预加载的应用列表
|
||||
- importEntryOpts - 可选 - 加载配置
|
||||
|
||||
- 类型
|
||||
|
||||
- `AppMetadata`
|
||||
- name - `string` - 必选 - 应用名
|
||||
- entry - `string | { scripts?: string[]; styles?: string[]; html?: string }` - 必选,微应用的 entry 地址
|
||||
|
|
@ -361,7 +352,10 @@ toc: menu
|
|||
```ts
|
||||
import { prefetchApps } from 'qiankun';
|
||||
|
||||
prefetchApps([ { name: 'app1', entry: '//locahost:7001' }, { name: 'app2', entry: '//locahost:7002' } ])
|
||||
prefetchApps([
|
||||
{ name: 'app1', entry: '//locahost:7001' },
|
||||
{ name: 'app2', entry: '//locahost:7002' },
|
||||
]);
|
||||
```
|
||||
|
||||
## [addErrorHandler/removeErrorHandler](https://single-spa.js.org/docs/api#adderrorhandler)
|
||||
|
|
@ -381,7 +375,7 @@ toc: menu
|
|||
```ts
|
||||
import { addGlobalUncaughtErrorHandler } from 'qiankun';
|
||||
|
||||
addGlobalUncaughtErrorHandler(event => console.log(event));
|
||||
addGlobalUncaughtErrorHandler((event) => console.log(event));
|
||||
```
|
||||
|
||||
## `removeGlobalUncaughtErrorHandler(handler)`
|
||||
|
|
@ -425,6 +419,7 @@ toc: menu
|
|||
- 示例
|
||||
|
||||
主应用:
|
||||
|
||||
```ts
|
||||
import { initGlobalState, MicroAppStateActions } from 'qiankun';
|
||||
|
||||
|
|
@ -440,10 +435,10 @@ toc: menu
|
|||
```
|
||||
|
||||
微应用:
|
||||
|
||||
```ts
|
||||
// 从生命周期 mount 中获取通信方法,使用方式和 master 一致
|
||||
export function mount(props) {
|
||||
|
||||
props.onGlobalStateChange((state, prev) => {
|
||||
// state: 变更后的状态; prev 变更前的状态
|
||||
console.log(state, prev);
|
||||
|
|
|
|||
|
|
@ -32,12 +32,13 @@ registerMicroApps([
|
|||
2. When the micro app is in the `hash` mode, the performance of the three routes is inconsistent
|
||||
|
||||
| routing | main app jump `/app/#/about` | special configuration |
|
||||
| ---------------| -------------------------------| --------------------------|
|
||||
| -------------- | ------------------------------ | ------------------------- |
|
||||
| vue-router | Response `about` routing | none |
|
||||
| react-router | not responding `about` routing | none |
|
||||
| angular-router | Response `about` routing | need to set `--base-href` |
|
||||
|
||||
`Angular` app set `--base-href` in `package.json`:
|
||||
|
||||
```diff
|
||||
- "start": "ng serve",
|
||||
+ "start": "ng serve --base-href /angular9",
|
||||
|
|
@ -50,8 +51,11 @@ registerMicroApps([
|
|||
- Solution 1: Modify `public-path.js` to:
|
||||
|
||||
```js
|
||||
__webpack_public_path__ = window.__POWERED_BY_QIANKUN__ ? window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__ : `http://${ip}:${port}/`; // Fill in your actual deployment address
|
||||
__webpack_public_path__ = window.__POWERED_BY_QIANKUN__
|
||||
? window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__
|
||||
: `http://${ip}:${port}/`; // Fill in your actual deployment address
|
||||
```
|
||||
|
||||
- Solution 2: Modify the bundling command and deploy the micro app in the `angular9` directory:
|
||||
|
||||
```diff
|
||||
|
|
@ -66,7 +70,7 @@ When the micro apps are all in the `hash` mode, `hash` can be used to distinguis
|
|||
When registering micro apps, `activeRule` needs to be written like this:
|
||||
|
||||
```js
|
||||
const getActiveRule = hash => location => location.hash.startsWith(hash);
|
||||
const getActiveRule = (hash) => (location) => location.hash.startsWith(hash);
|
||||
registerMicroApps([
|
||||
{
|
||||
name: 'app-hash',
|
||||
|
|
@ -91,9 +95,9 @@ const routes = [
|
|||
component: Home,
|
||||
children: [
|
||||
// All other routes are written here
|
||||
]
|
||||
}
|
||||
]
|
||||
],
|
||||
},
|
||||
];
|
||||
```
|
||||
|
||||
### When there are multiple micro apps at the same time
|
||||
|
|
@ -148,7 +152,7 @@ Suppose we have a main app and 6 micro apps ( respectively `vue-hash`, `vue-hist
|
|||
At this time, you need to set the `publicPath` and the route `base` of the `history` mode when the micro app is built, and then bundle them into the corresponding directory.
|
||||
|
||||
| app | routing base | publicPath | real access path |
|
||||
| --------------- | ------------------------| ------------------------| ---------------------------------------------|
|
||||
| --------------- | ----------------------- | ----------------------- | -------------------------------------------- |
|
||||
| vue-hash | none | /child/vue-hash/ | http://localhost:8080/child/vue-hash/ |
|
||||
| vue-history | /child/vue-history/ | /child/vue-history/ | http://localhost:8080/child/vue-history/ |
|
||||
| react-hash | none | /child/react-hash/ | http://localhost:8080/child/react-hash/ |
|
||||
|
|
@ -159,41 +163,52 @@ At this time, you need to set the `publicPath` and the route `base` of the `hist
|
|||
- `vue-history` micro app
|
||||
|
||||
Routing's base configuration:
|
||||
|
||||
```js
|
||||
base: window.__POWERED_BY_QIANKUN__ ? '/app-vue/' : '/child/vue-history/',
|
||||
```
|
||||
|
||||
Webpack's publicPath configuration(`vue.config.js`):
|
||||
|
||||
```js
|
||||
module.exports = {
|
||||
publicPath: '/child/vue-history/'
|
||||
}
|
||||
publicPath: '/child/vue-history/',
|
||||
};
|
||||
```
|
||||
|
||||
- `react-history` micro app
|
||||
|
||||
Routing's base configuration:
|
||||
|
||||
```html
|
||||
<BrowserRouter basename={window.__POWERED_BY_QIANKUN__ ? '/app-react' : '/child/react-history/'}>
|
||||
```
|
||||
|
||||
Webpack's publicPath configuration:
|
||||
|
||||
```js
|
||||
module.exports = {
|
||||
output: {
|
||||
publicPath: '/child/react-history/',
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
```
|
||||
|
||||
- `angular-history` micro app
|
||||
|
||||
Routing's base configuration:
|
||||
|
||||
```js
|
||||
providers: [{
|
||||
providers: [
|
||||
{
|
||||
provide: APP_BASE_HREF,
|
||||
useValue: window.__POWERED_BY_QIANKUN__ ? '/app-angular/' : '/child/angular-history/'
|
||||
}]
|
||||
useValue: window.__POWERED_BY_QIANKUN__ ? '/app-angular/' : '/child/angular-history/',
|
||||
},
|
||||
];
|
||||
```
|
||||
|
||||
The `publicPath` of webpack is set by `deploy-url`, modify `package.json`:
|
||||
|
||||
```diff
|
||||
- "build": "ng build",
|
||||
+ "build": "ng build --deploy-url /child/angular-history/",
|
||||
|
|
@ -293,8 +308,8 @@ For micro apps bundled by `webpack`, the `publicPath` bundled by the micro app's
|
|||
module.exports = {
|
||||
output: {
|
||||
publicPath: `/app1/`,
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
```
|
||||
|
||||
After adding `/app1/` to the `publicPath` of the micro app, it must be deployed in the `/app1` directory, otherwise it cannot be accessed independently.
|
||||
|
|
|
|||
|
|
@ -32,12 +32,13 @@ registerMicroApps([
|
|||
2. 当微应用是 `hash` 模式时,三种路由的表现不一致
|
||||
|
||||
| 路由 | 主应用跳转/app/#/about | 特殊配置 |
|
||||
| ---------------| ----------------------| --------------------|
|
||||
| -------------- | ---------------------- | -------------------- |
|
||||
| vue-router | 响应 about 路由 | 无 |
|
||||
| react-router | 不响应 about 路由 | 无 |
|
||||
| angular-router | 响应 about 路由 | 需要设置 --base-href |
|
||||
|
||||
`angular` 应用在 `package.json` 里面设置 `--base-href`:
|
||||
|
||||
```diff
|
||||
- "start": "ng serve",
|
||||
+ "start": "ng serve --base-href /angular9",
|
||||
|
|
@ -50,8 +51,11 @@ registerMicroApps([
|
|||
- 方法 1:修改 `public-path.js` 为:
|
||||
|
||||
```js
|
||||
__webpack_public_path__ = window.__POWERED_BY_QIANKUN__ ? window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__ : `http://${ip}:${port}/`; // 填写你的实际部署地址
|
||||
__webpack_public_path__ = window.__POWERED_BY_QIANKUN__
|
||||
? window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__
|
||||
: `http://${ip}:${port}/`; // 填写你的实际部署地址
|
||||
```
|
||||
|
||||
- 方法 2:修改打包命令,并且将微应用部署在 `angular9` 目录:
|
||||
|
||||
```diff
|
||||
|
|
@ -66,7 +70,7 @@ registerMicroApps([
|
|||
注册微应用时 `activeRule` 需要这样写:
|
||||
|
||||
```js
|
||||
const getActiveRule = hash => location => location.hash.startsWith(hash);
|
||||
const getActiveRule = (hash) => (location) => location.hash.startsWith(hash);
|
||||
registerMicroApps([
|
||||
{
|
||||
name: 'app-hash',
|
||||
|
|
@ -90,9 +94,9 @@ const routes = [
|
|||
component: Home,
|
||||
children: [
|
||||
// 其他的路由都写到这里
|
||||
]
|
||||
}
|
||||
]
|
||||
],
|
||||
},
|
||||
];
|
||||
```
|
||||
|
||||
### 同时存在多个微应用时
|
||||
|
|
@ -128,6 +132,7 @@ const routes = [
|
|||
#### 方案 1:微应用都放在在一个特殊名称(**不会和微应用重名**)的文件夹下(**建议使用**)
|
||||
|
||||
假设我们有一个主应用和 6 个微应用(分别为 `vue-hash`、`vue-history`、`react-hash`、`react-history`、`angular-hash`、`angular-history` ),打包后如下放置:
|
||||
|
||||
```
|
||||
└── html/ # 根文件夹
|
||||
|
|
||||
|
|
@ -146,7 +151,7 @@ const routes = [
|
|||
此时需要设置微应用构建时的 `publicPath` 和 `history` 模式的路由 `base`,然后才能打包放到对应的目录里。
|
||||
|
||||
| 项目 | 路由 base | publicPath | 真实访问路径 |
|
||||
| --------------- | ------------------------| ------------------------| ---------------------------------------------|
|
||||
| --------------- | ----------------------- | ----------------------- | -------------------------------------------- |
|
||||
| vue-hash | 无 | /child/vue-hash/ | http://localhost:8080/child/vue-hash/ |
|
||||
| vue-history | /child/vue-history/ | /child/vue-history/ | http://localhost:8080/child/vue-history/ |
|
||||
| react-hash | 无 | /child/react-hash/ | http://localhost:8080/child/react-hash/ |
|
||||
|
|
@ -157,41 +162,52 @@ const routes = [
|
|||
- vue-history 微应用
|
||||
|
||||
路由设置:
|
||||
|
||||
```js
|
||||
base: window.__POWERED_BY_QIANKUN__ ? '/app-vue/' : '/child/vue-history/',
|
||||
```
|
||||
|
||||
webpack 打包 publicPath 配置(`vue.config.js`):
|
||||
|
||||
```js
|
||||
module.exports = {
|
||||
publicPath: '/child/vue-history/'
|
||||
}
|
||||
publicPath: '/child/vue-history/',
|
||||
};
|
||||
```
|
||||
|
||||
- react-history 微应用
|
||||
|
||||
路由设置:
|
||||
|
||||
```html
|
||||
<BrowserRouter basename={window.__POWERED_BY_QIANKUN__ ? '/app-react' : '/child/react-history/'}>
|
||||
```
|
||||
|
||||
webpack 打包 publicPath 配置:
|
||||
|
||||
```js
|
||||
module.exports = {
|
||||
output: {
|
||||
publicPath: '/child/react-history/',
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
```
|
||||
|
||||
- angular-history 微应用
|
||||
|
||||
路由设置:
|
||||
|
||||
```js
|
||||
providers: [{
|
||||
providers: [
|
||||
{
|
||||
provide: APP_BASE_HREF,
|
||||
useValue: window.__POWERED_BY_QIANKUN__ ? '/app-angular/' : '/child/angular-history/'
|
||||
}]
|
||||
useValue: window.__POWERED_BY_QIANKUN__ ? '/app-angular/' : '/child/angular-history/',
|
||||
},
|
||||
];
|
||||
```
|
||||
|
||||
webpack 打包的 `publicPath` 通过 `deploy-url` 来修改,修改 `package.json`:
|
||||
|
||||
```diff
|
||||
- "build": "ng build",
|
||||
+ "build": "ng build --deploy-url /child/angular-history/",
|
||||
|
|
@ -291,8 +307,8 @@ registerMicroApps([
|
|||
module.exports = {
|
||||
output: {
|
||||
publicPath: `/app1/`,
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
```
|
||||
|
||||
微应用打包的 `publicPath` 加上 `/app1/` 之后,必须部署在 `/app1` 目录,否则无法独立访问。
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ To solve the exception, try the following steps:
|
|||
4. Check your `package.json` name field is unique between sub apps.
|
||||
|
||||
5. Check if the entry js in the sub-app's entry HTML is the last script to load. If not, move the order to make it be the last, or manually mark the entry js as `entry` in the HTML, such as:
|
||||
|
||||
```html {2}
|
||||
<script src="/antd.js"></script>
|
||||
<script src="/appEntry.js" entry></script>
|
||||
|
|
@ -29,8 +30,7 @@ To solve the exception, try the following steps:
|
|||
|
||||
6. If the development environment is OK but the production environment is not, check whether the `index.html` and `entry js` of the micro app are returned normally, for example, `404.html` is returned.
|
||||
|
||||
7. If you're using webpack5, please see [here](https://github.com/umijs/qiankun/issues/1092)
|
||||
If it still not works after the steps above, this is usually due to browser compatibility issues. Try to **set the webpack `output.library` of the broken sub app the same with your main app registration for your app**, such as:
|
||||
7. If you're using webpack5, please see [here](https://github.com/umijs/qiankun/issues/1092) If it still not works after the steps above, this is usually due to browser compatibility issues. Try to **set the webpack `output.library` of the broken sub app the same with your main app registration for your app**, such as:
|
||||
|
||||
Such as here is the main configuration:
|
||||
|
||||
|
|
@ -66,13 +66,14 @@ This error thrown as the container DOM does not exist after the micro app is loa
|
|||
1. The root id of the micro app conflicts with other DOM, and the solution is to modify the search range of the root id.
|
||||
|
||||
`vue` micro app:
|
||||
|
||||
```js
|
||||
function render(props = {}) {
|
||||
const { container } = props;
|
||||
instance = new Vue({
|
||||
router,
|
||||
store,
|
||||
render: h => h(App),
|
||||
render: (h) => h(App),
|
||||
}).$mount(container ? container.querySelector('#app') : '#app');
|
||||
}
|
||||
export async function mount(props) {
|
||||
|
|
@ -81,6 +82,7 @@ This error thrown as the container DOM does not exist after the micro app is loa
|
|||
```
|
||||
|
||||
`react` micro app:
|
||||
|
||||
```js
|
||||
function render(props) {
|
||||
const { container } = props;
|
||||
|
|
@ -132,8 +134,8 @@ It must be ensured that the routing page of the main app is also loaded when the
|
|||
path: '/portal/*',
|
||||
name: 'portal',
|
||||
component: () => import('../views/Portal.vue'),
|
||||
}
|
||||
]
|
||||
},
|
||||
];
|
||||
```
|
||||
2. The `activeRule` of the micro app needs to include the route `path` of the main app.
|
||||
```js
|
||||
|
|
@ -156,7 +158,7 @@ It must be ensured that the routing page of the main app is also loaded when the
|
|||
start();
|
||||
}
|
||||
},
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
`react` + `react-router` main app:only need to make the activeRule of the sub app include the route of the main app.
|
||||
|
|
@ -170,12 +172,11 @@ It must be ensured that the routing page of the main app is also loaded when the
|
|||
{
|
||||
path: 'portal',
|
||||
component: PortalComponent,
|
||||
children: [
|
||||
{ path: '**', component: EmptyComponent },
|
||||
],
|
||||
children: [{ path: '**', component: EmptyComponent }],
|
||||
},
|
||||
];
|
||||
```
|
||||
|
||||
2. The `activeRule` of the micro app needs to include the route `path` of the main app.
|
||||
```js
|
||||
registerMicroApps([
|
||||
|
|
@ -208,7 +209,7 @@ There are three lines code in the `vue-router` as followed, and it will access `
|
|||
|
||||
```javascript
|
||||
if (inBrowser && window.Vue) {
|
||||
window.Vue.use(VueRouter)
|
||||
window.Vue.use(VueRouter);
|
||||
}
|
||||
```
|
||||
|
||||
|
|
@ -282,26 +283,16 @@ There are mainly the following solutions:
|
|||
```js
|
||||
module.exports = {
|
||||
chainWebpack: (config) => {
|
||||
config.module
|
||||
.rule('fonts')
|
||||
.use('url-loader')
|
||||
.loader('url-loader')
|
||||
.options({})
|
||||
.end()
|
||||
config.module
|
||||
.rule('images')
|
||||
.use('url-loader')
|
||||
.loader('url-loader')
|
||||
.options({})
|
||||
.end()
|
||||
config.module.rule('fonts').use('url-loader').loader('url-loader').options({}).end();
|
||||
config.module.rule('images').use('url-loader').loader('url-loader').options({}).end();
|
||||
},
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
3. Use the `file-loader` of `webpack` to inject the full path when packaging it (suitable for projects with large font files and images)
|
||||
|
||||
```js
|
||||
const publicPath = process.env.NODE_ENV === "production" ? 'https://qiankun.umijs.org/' : `http://localhost:${port}`;
|
||||
const publicPath = process.env.NODE_ENV === 'production' ? 'https://qiankun.umijs.org/' : `http://localhost:${port}`;
|
||||
module.exports = {
|
||||
module: {
|
||||
rules: [
|
||||
|
|
@ -312,7 +303,7 @@ There are mainly the following solutions:
|
|||
loader: 'file-loader',
|
||||
options: {
|
||||
name: 'img/[name].[hash:8].[ext]',
|
||||
publicPath
|
||||
publicPath,
|
||||
},
|
||||
},
|
||||
],
|
||||
|
|
@ -324,7 +315,7 @@ There are mainly the following solutions:
|
|||
loader: 'file-loader',
|
||||
options: {
|
||||
name: 'fonts/[name].[hash:8].[ext]',
|
||||
publicPath
|
||||
publicPath,
|
||||
},
|
||||
},
|
||||
],
|
||||
|
|
@ -337,7 +328,7 @@ There are mainly the following solutions:
|
|||
`vue-cli3` project:
|
||||
|
||||
```js
|
||||
const publicPath = process.env.NODE_ENV === "production" ? 'https://qiankun.umijs.org/' : `http://localhost:${port}`;
|
||||
const publicPath = process.env.NODE_ENV === 'production' ? 'https://qiankun.umijs.org/' : `http://localhost:${port}`;
|
||||
module.exports = {
|
||||
chainWebpack: (config) => {
|
||||
const fontRule = config.module.rule('fonts');
|
||||
|
|
@ -347,9 +338,9 @@ There are mainly the following solutions:
|
|||
.loader('file-loader')
|
||||
.options({
|
||||
name: 'fonts/[name].[hash:8].[ext]',
|
||||
publicPath
|
||||
publicPath,
|
||||
})
|
||||
.end()
|
||||
.end();
|
||||
const imgRule = config.module.rule('images');
|
||||
imgRule.uses.clear();
|
||||
imgRule
|
||||
|
|
@ -357,17 +348,17 @@ There are mainly the following solutions:
|
|||
.loader('file-loader')
|
||||
.options({
|
||||
name: 'img/[name].[hash:8].[ext]',
|
||||
publicPath
|
||||
publicPath,
|
||||
})
|
||||
.end()
|
||||
.end();
|
||||
},
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
4. Combine the two schemes, convert small files to `base64`, and inject path prefixes for large files
|
||||
|
||||
```js
|
||||
const publicPath = process.env.NODE_ENV === "production" ? 'https://qiankun.umijs.org/' : `http://localhost:${port}`;
|
||||
const publicPath = process.env.NODE_ENV === 'production' ? 'https://qiankun.umijs.org/' : `http://localhost:${port}`;
|
||||
module.exports = {
|
||||
module: {
|
||||
rules: [
|
||||
|
|
@ -381,9 +372,9 @@ There are mainly the following solutions:
|
|||
loader: 'file-loader',
|
||||
options: {
|
||||
name: 'img/[name].[hash:8].[ext]',
|
||||
publicPath
|
||||
}
|
||||
}
|
||||
publicPath,
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
|
|
@ -397,9 +388,9 @@ There are mainly the following solutions:
|
|||
loader: 'file-loader',
|
||||
options: {
|
||||
name: 'fonts/[name].[hash:8].[ext]',
|
||||
publicPath
|
||||
}
|
||||
}
|
||||
publicPath,
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
|
|
@ -411,10 +402,11 @@ There are mainly the following solutions:
|
|||
`vue-cli3` project:
|
||||
|
||||
```js
|
||||
const publicPath = process.env.NODE_ENV === "production" ? 'https://qiankun.umijs.org/' : `http://localhost:${port}`;
|
||||
const publicPath = process.env.NODE_ENV === 'production' ? 'https://qiankun.umijs.org/' : `http://localhost:${port}`;
|
||||
module.exports = {
|
||||
chainWebpack: (config) => {
|
||||
config.module.rule('fonts')
|
||||
config.module
|
||||
.rule('fonts')
|
||||
.use('url-loader')
|
||||
.loader('url-loader')
|
||||
.options({
|
||||
|
|
@ -423,12 +415,13 @@ There are mainly the following solutions:
|
|||
loader: 'file-loader',
|
||||
options: {
|
||||
name: 'fonts/[name].[hash:8].[ext]',
|
||||
publicPath
|
||||
}
|
||||
}
|
||||
publicPath,
|
||||
},
|
||||
},
|
||||
})
|
||||
.end();
|
||||
config.module.rule('images')
|
||||
config.module
|
||||
.rule('images')
|
||||
.use('url-loader')
|
||||
.loader('url-loader')
|
||||
.options({
|
||||
|
|
@ -437,12 +430,12 @@ There are mainly the following solutions:
|
|||
loader: 'file-loader',
|
||||
options: {
|
||||
name: 'img/[name].[hash:8].[ext]',
|
||||
publicPath
|
||||
}
|
||||
}
|
||||
})
|
||||
publicPath,
|
||||
},
|
||||
}
|
||||
},
|
||||
});
|
||||
},
|
||||
};
|
||||
```
|
||||
|
||||
5. The `vue-cli3` project can package `css` into `js` without generating files separately (not recommended, only suitable for projects with less `css`)
|
||||
|
|
@ -452,9 +445,9 @@ There are mainly the following solutions:
|
|||
```js
|
||||
module.exports = {
|
||||
css: {
|
||||
extract: false
|
||||
extract: false,
|
||||
},
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
## Must a sub app asset support cors?
|
||||
|
|
@ -585,10 +578,11 @@ In singular mode, you can use the `excludeAssetFilter` parameter to release this
|
|||
If you use JSONP in not-singular mode, simply using `excludeAssetFilter` does not achieve good results, because each application is isolated by the sandbox; you can provide a unified JSONP tool in the main application, and the subapplication just calls the tool.
|
||||
|
||||
## 404 after refresh of child application?
|
||||
It is usually because you are routing in Browser mode, which requires the server to open it.
|
||||
Specific configuration mode reference:
|
||||
* [HTML5 History Mode](https://router.vuejs.org/guide/essentials/history-mode.html)
|
||||
* [browserRouter](https://reactrouter.com/web/api/BrowserRouter)
|
||||
|
||||
It is usually because you are routing in Browser mode, which requires the server to open it. Specific configuration mode reference:
|
||||
|
||||
- [HTML5 History Mode](https://router.vuejs.org/guide/essentials/history-mode.html)
|
||||
- [browserRouter](https://reactrouter.com/web/api/BrowserRouter)
|
||||
|
||||
## How to configure the 404 page in the main application?
|
||||
|
||||
|
|
@ -599,14 +593,15 @@ Take `vue-router` as an example, the pseudo code is as follows:
|
|||
```js
|
||||
const childrenPath = ['/app1', '/app2'];
|
||||
router.beforeEach((to, from, next) => {
|
||||
if(to.name) {// There is a name attribute, indicating that it is the route of the main project
|
||||
next()
|
||||
if (to.name) {
|
||||
// There is a name attribute, indicating that it is the route of the main project
|
||||
next();
|
||||
}
|
||||
if(childrenPath.some(item => to.path.includes(item))){
|
||||
next()
|
||||
if (childrenPath.some((item) => to.path.includes(item))) {
|
||||
next();
|
||||
}
|
||||
next({ name: '404' })
|
||||
})
|
||||
next({ name: '404' });
|
||||
});
|
||||
```
|
||||
|
||||
## How to jump between micro apps?
|
||||
|
|
@ -620,7 +615,6 @@ router.beforeEach((to, from, next) => {
|
|||
1. `history.pushState()`: [mdn usage introduction](https://developer.mozilla.org/zh-CN/docs/Web/API/History/pushState)
|
||||
2. Pass the routing instance of the main application to the micro application through `props`, and the micro application will jump to this routing instance.
|
||||
|
||||
|
||||
## After the microapp file is updated, the old version of the file is still accessed
|
||||
|
||||
The server needs to configure a response header for the `index.html` of the micro application: `Cache-Control no-cache`, which means to check whether it is updated every time it requests.
|
||||
|
|
@ -642,8 +636,8 @@ loadMicroApp({
|
|||
name: 'configEntry',
|
||||
entry: {
|
||||
scripts: ['//t.com/t.js'],
|
||||
styles: ['//t.com/t.css']
|
||||
}
|
||||
styles: ['//t.com/t.css'],
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
|
|
@ -654,6 +648,7 @@ export async function mount(props) {
|
|||
ReactDOM.render(<App />, props.container);
|
||||
}
|
||||
```
|
||||
|
||||
As `props.container` is not an empty container and will contain information such as the style sheet that the microapp registers through the styles configuration, when we render directly for the container that the react application is applying with 'props.container', all the original DOM structures in the container will be overwritten, causing the style sheet to be lost.
|
||||
|
||||
We need to build an empty render container for micro applications that use Config Entry to mount react applications:
|
||||
|
|
@ -682,7 +677,7 @@ export async function mount(props) {
|
|||
|
||||
As the requests to pull micro-app entry are all cross-domain, when your micro-app relies on cookies (such as authentication), you need to customize the fetch method to enable the cors mode:
|
||||
|
||||
* If you load the microapps through [registerMicroApps](/api#registermicroappsapps-lifecycles), you need to configure a custom fetch in the start method, such as:
|
||||
- If you load the microapps through [registerMicroApps](/api#registermicroappsapps-lifecycles), you need to configure a custom fetch in the start method, such as:
|
||||
|
||||
```js
|
||||
import { start } from 'qiankun';
|
||||
|
|
@ -699,11 +694,11 @@ As the requests to pull micro-app entry are all cross-domain, when your micro-ap
|
|||
}
|
||||
|
||||
return window.fetch(url, ...args);
|
||||
}
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
* If you load the microapp via [loadMicroApp](/api#loadmicroappapp-configuration), you need to configure a custom fetch when invoking, such as:
|
||||
- If you load the microapp via [loadMicroApp](/api#loadmicroappapp-configuration), you need to configure a custom fetch when invoking, such as:
|
||||
|
||||
```js
|
||||
import { loadMicroApp } from 'qiankun';
|
||||
|
|
@ -720,6 +715,6 @@ As the requests to pull micro-app entry are all cross-domain, when your micro-ap
|
|||
}
|
||||
|
||||
return window.fetch(url, ...args);
|
||||
}
|
||||
},
|
||||
});
|
||||
```
|
||||
|
|
|
|||
|
|
@ -68,13 +68,14 @@ qiankun 抛出这个错误是因为微应用加载后容器 DOM 节点不存在
|
|||
1. 微应用的根 `id` 与其他 DOM 冲突。解决办法是:修改根 `id` 的查找范围。
|
||||
|
||||
`vue` 微应用:
|
||||
|
||||
```js
|
||||
function render(props = {}) {
|
||||
const { container } = props;
|
||||
instance = new Vue({
|
||||
router,
|
||||
store,
|
||||
render: h => h(App),
|
||||
render: (h) => h(App),
|
||||
}).$mount(container ? container.querySelector('#app') : '#app');
|
||||
}
|
||||
export async function mount(props) {
|
||||
|
|
@ -83,6 +84,7 @@ qiankun 抛出这个错误是因为微应用加载后容器 DOM 节点不存在
|
|||
```
|
||||
|
||||
`react` 微应用:
|
||||
|
||||
```js
|
||||
function render(props) {
|
||||
const { container } = props;
|
||||
|
|
@ -134,8 +136,8 @@ qiankun 抛出这个错误是因为微应用加载后容器 DOM 节点不存在
|
|||
path: '/portal/*',
|
||||
name: 'portal',
|
||||
component: () => import('../views/Portal.vue'),
|
||||
}
|
||||
]
|
||||
},
|
||||
];
|
||||
```
|
||||
2. 微应用的 `activeRule` 需要包含主应用的这个路由 `path`。
|
||||
```js
|
||||
|
|
@ -158,7 +160,7 @@ qiankun 抛出这个错误是因为微应用加载后容器 DOM 节点不存在
|
|||
start();
|
||||
}
|
||||
},
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
`react` + `react-router` 技术栈的主应用:只需要让微应用的 `activeRule` 包含主应用的这个路由即可。
|
||||
|
|
@ -172,12 +174,11 @@ qiankun 抛出这个错误是因为微应用加载后容器 DOM 节点不存在
|
|||
{
|
||||
path: 'portal',
|
||||
component: PortalComponent,
|
||||
children: [
|
||||
{ path: '**', component: EmptyComponent },
|
||||
],
|
||||
children: [{ path: '**', component: EmptyComponent }],
|
||||
},
|
||||
];
|
||||
```
|
||||
|
||||
2. 微应用的 `activeRule` 需要包含主应用的这个路由 `path`。
|
||||
```js
|
||||
registerMicroApps([
|
||||
|
|
@ -201,6 +202,7 @@ qiankun 抛出这个错误是因为微应用加载后容器 DOM 节点不存在
|
|||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Vue Router 报错 `Uncaught TypeError: Cannot redefine property: $router`
|
||||
|
||||
qiankun 中的代码使用 Proxy 去代理父页面的 window,来实现的沙箱,在微应用中访问 `window.Vue` 时,会先在自己的 window 里查找有没有 `Vue` 属性,如果没有就去父应用里查找。
|
||||
|
|
@ -209,7 +211,7 @@ qiankun 中的代码使用 Proxy 去代理父页面的 window,来实现的沙
|
|||
|
||||
```javascript
|
||||
if (inBrowser && window.Vue) {
|
||||
window.Vue.use(VueRouter)
|
||||
window.Vue.use(VueRouter);
|
||||
}
|
||||
```
|
||||
|
||||
|
|
@ -285,26 +287,16 @@ runtime publicPath 主要解决的是微应用动态载入的 脚本、样式、
|
|||
```js
|
||||
module.exports = {
|
||||
chainWebpack: (config) => {
|
||||
config.module
|
||||
.rule('fonts')
|
||||
.use('url-loader')
|
||||
.loader('url-loader')
|
||||
.options({})
|
||||
.end()
|
||||
config.module
|
||||
.rule('images')
|
||||
.use('url-loader')
|
||||
.loader('url-loader')
|
||||
.options({})
|
||||
.end()
|
||||
config.module.rule('fonts').use('url-loader').loader('url-loader').options({}).end();
|
||||
config.module.rule('images').use('url-loader').loader('url-loader').options({}).end();
|
||||
},
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
3. 借助 `webpack` 的 `file-loader` ,在打包时给其注入完整路径(适用于字体文件和图片体积比较大的项目)
|
||||
|
||||
```js
|
||||
const publicPath = process.env.NODE_ENV === "production" ? 'https://qiankun.umijs.org/' : `http://localhost:${port}`;
|
||||
const publicPath = process.env.NODE_ENV === 'production' ? 'https://qiankun.umijs.org/' : `http://localhost:${port}`;
|
||||
module.exports = {
|
||||
module: {
|
||||
rules: [
|
||||
|
|
@ -315,7 +307,7 @@ runtime publicPath 主要解决的是微应用动态载入的 脚本、样式、
|
|||
loader: 'file-loader',
|
||||
options: {
|
||||
name: 'img/[name].[hash:8].[ext]',
|
||||
publicPath
|
||||
publicPath,
|
||||
},
|
||||
},
|
||||
],
|
||||
|
|
@ -327,7 +319,7 @@ runtime publicPath 主要解决的是微应用动态载入的 脚本、样式、
|
|||
loader: 'file-loader',
|
||||
options: {
|
||||
name: 'fonts/[name].[hash:8].[ext]',
|
||||
publicPath
|
||||
publicPath,
|
||||
},
|
||||
},
|
||||
],
|
||||
|
|
@ -340,7 +332,7 @@ runtime publicPath 主要解决的是微应用动态载入的 脚本、样式、
|
|||
`vue-cli3` 项目写法:
|
||||
|
||||
```js
|
||||
const publicPath = process.env.NODE_ENV === "production" ? 'https://qiankun.umijs.org/' : `http://localhost:${port}`;
|
||||
const publicPath = process.env.NODE_ENV === 'production' ? 'https://qiankun.umijs.org/' : `http://localhost:${port}`;
|
||||
module.exports = {
|
||||
chainWebpack: (config) => {
|
||||
const fontRule = config.module.rule('fonts');
|
||||
|
|
@ -350,9 +342,9 @@ runtime publicPath 主要解决的是微应用动态载入的 脚本、样式、
|
|||
.loader('file-loader')
|
||||
.options({
|
||||
name: 'fonts/[name].[hash:8].[ext]',
|
||||
publicPath
|
||||
publicPath,
|
||||
})
|
||||
.end()
|
||||
.end();
|
||||
const imgRule = config.module.rule('images');
|
||||
imgRule.uses.clear();
|
||||
imgRule
|
||||
|
|
@ -360,17 +352,17 @@ runtime publicPath 主要解决的是微应用动态载入的 脚本、样式、
|
|||
.loader('file-loader')
|
||||
.options({
|
||||
name: 'img/[name].[hash:8].[ext]',
|
||||
publicPath
|
||||
publicPath,
|
||||
})
|
||||
.end()
|
||||
.end();
|
||||
},
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
4. 将两种方案结合起来,小文件转 `base64` ,大文件注入路径前缀
|
||||
|
||||
```js
|
||||
const publicPath = process.env.NODE_ENV === "production" ? 'https://qiankun.umijs.org/' : `http://localhost:${port}`;
|
||||
const publicPath = process.env.NODE_ENV === 'production' ? 'https://qiankun.umijs.org/' : `http://localhost:${port}`;
|
||||
module.exports = {
|
||||
module: {
|
||||
rules: [
|
||||
|
|
@ -384,9 +376,9 @@ runtime publicPath 主要解决的是微应用动态载入的 脚本、样式、
|
|||
loader: 'file-loader',
|
||||
options: {
|
||||
name: 'img/[name].[hash:8].[ext]',
|
||||
publicPath
|
||||
}
|
||||
}
|
||||
publicPath,
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
|
|
@ -400,9 +392,9 @@ runtime publicPath 主要解决的是微应用动态载入的 脚本、样式、
|
|||
loader: 'file-loader',
|
||||
options: {
|
||||
name: 'fonts/[name].[hash:8].[ext]',
|
||||
publicPath
|
||||
}
|
||||
}
|
||||
publicPath,
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
|
|
@ -414,10 +406,11 @@ runtime publicPath 主要解决的是微应用动态载入的 脚本、样式、
|
|||
`vue-cli3` 项目写法:
|
||||
|
||||
```js
|
||||
const publicPath = process.env.NODE_ENV === "production" ? 'https://qiankun.umijs.org/' : `http://localhost:${port}`;
|
||||
const publicPath = process.env.NODE_ENV === 'production' ? 'https://qiankun.umijs.org/' : `http://localhost:${port}`;
|
||||
module.exports = {
|
||||
chainWebpack: (config) => {
|
||||
config.module.rule('fonts')
|
||||
config.module
|
||||
.rule('fonts')
|
||||
.use('url-loader')
|
||||
.loader('url-loader')
|
||||
.options({
|
||||
|
|
@ -426,12 +419,13 @@ runtime publicPath 主要解决的是微应用动态载入的 脚本、样式、
|
|||
loader: 'file-loader',
|
||||
options: {
|
||||
name: 'fonts/[name].[hash:8].[ext]',
|
||||
publicPath
|
||||
}
|
||||
}
|
||||
publicPath,
|
||||
},
|
||||
},
|
||||
})
|
||||
.end();
|
||||
config.module.rule('images')
|
||||
config.module
|
||||
.rule('images')
|
||||
.use('url-loader')
|
||||
.loader('url-loader')
|
||||
.options({
|
||||
|
|
@ -440,12 +434,12 @@ runtime publicPath 主要解决的是微应用动态载入的 脚本、样式、
|
|||
loader: 'file-loader',
|
||||
options: {
|
||||
name: 'img/[name].[hash:8].[ext]',
|
||||
publicPath
|
||||
}
|
||||
}
|
||||
})
|
||||
publicPath,
|
||||
},
|
||||
}
|
||||
},
|
||||
});
|
||||
},
|
||||
};
|
||||
```
|
||||
|
||||
5. `vue-cli3` 项目可以将 `css` 打包到 `js`里面,不单独生成文件(不推荐,仅适用于 `css` 较少的项目)
|
||||
|
|
@ -455,9 +449,9 @@ runtime publicPath 主要解决的是微应用动态载入的 脚本、样式、
|
|||
```js
|
||||
module.exports = {
|
||||
css: {
|
||||
extract: false
|
||||
extract: false,
|
||||
},
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
## 微应用静态资源一定要支持跨域吗?
|
||||
|
|
@ -490,7 +484,7 @@ import { start } from 'qiankun';
|
|||
start({
|
||||
getTemplate(tpl) {
|
||||
return tpl.replace('<script src="/to-be-replaced.js"><script>', '');
|
||||
}
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
|
|
@ -505,12 +499,14 @@ start({
|
|||
fetch(url, ...args) {
|
||||
if (url === 'http://to-be-replaced.js') {
|
||||
return {
|
||||
async text() { return '' }
|
||||
async text() {
|
||||
return '';
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
return window.fetch(url, ...args);
|
||||
}
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
|
|
@ -656,10 +652,11 @@ qiankun 会将微应用的动态 script 加载(例如 JSONP)转化为 fetch
|
|||
若在多实例模式下使用 JSONP,单纯使用 `excludeAssetFilter` 并不能取得好的效果,因为各应用被沙箱所隔离;你可以在主应用提供统一的 JSONP 工具,微应用调用主应用提供的该工具来曲线救国。
|
||||
|
||||
## 微应用路径下刷新后 404?
|
||||
通常是因为你使用的是 browser 模式的路由,这种路由模式的开启需要服务端配合才行。
|
||||
具体配置方式参考:
|
||||
* [HTML5 History 模式](https://router.vuejs.org/zh/guide/essentials/history-mode.html)
|
||||
* [browserHistory](https://react-guide.github.io/react-router-cn/docs/guides/basics/Histories.html#browserHistory)
|
||||
|
||||
通常是因为你使用的是 browser 模式的路由,这种路由模式的开启需要服务端配合才行。具体配置方式参考:
|
||||
|
||||
- [HTML5 History 模式](https://router.vuejs.org/zh/guide/essentials/history-mode.html)
|
||||
- [browserHistory](https://react-guide.github.io/react-router-cn/docs/guides/basics/Histories.html#browserHistory)
|
||||
|
||||
## 主应用如何配置 404 页面?
|
||||
|
||||
|
|
@ -670,14 +667,15 @@ qiankun 会将微应用的动态 script 加载(例如 JSONP)转化为 fetch
|
|||
```js
|
||||
const childrenPath = ['/app1', '/app2'];
|
||||
router.beforeEach((to, from, next) => {
|
||||
if(to.name) { // 有 name 属性,说明是主应用的路由
|
||||
next()
|
||||
if (to.name) {
|
||||
// 有 name 属性,说明是主应用的路由
|
||||
next();
|
||||
}
|
||||
if(childrenPath.some(item => to.path.includes(item))){
|
||||
next()
|
||||
if (childrenPath.some((item) => to.path.includes(item))) {
|
||||
next();
|
||||
}
|
||||
next({ name: '404' })
|
||||
})
|
||||
next({ name: '404' });
|
||||
});
|
||||
```
|
||||
|
||||
## 微应用之间如何跳转?
|
||||
|
|
@ -691,7 +689,6 @@ router.beforeEach((to, from, next) => {
|
|||
1. `history.pushState()`:[mdn 用法介绍](https://developer.mozilla.org/zh-CN/docs/Web/API/History/pushState)
|
||||
2. 将主应用的路由实例通过 `props` 传给微应用,微应用这个路由实例跳转。
|
||||
|
||||
|
||||
## 微应用文件更新之后,访问的还是旧版文件
|
||||
|
||||
服务器需要给微应用的 `index.html` 配置一个响应头:`Cache-Control no-cache`,意思就是每次请求都检查是否更新。
|
||||
|
|
@ -713,8 +710,8 @@ loadMicroApp({
|
|||
name: 'configEntry',
|
||||
entry: {
|
||||
scripts: ['//t.com/t.js'],
|
||||
styles: ['//t.com/t.css']
|
||||
}
|
||||
styles: ['//t.com/t.css'],
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
|
|
@ -754,7 +751,7 @@ export async function mount(props) {
|
|||
|
||||
因为拉取微应用 entry 的请求都是跨域的,所以当你的微应用是依赖 cookie (如登陆鉴权)的情况下,你需要通过自定义 fetch 的方式,开启 fetch 的 cors 模式:
|
||||
|
||||
* 如果你是通过 [registerMicroApps](/zh/api#registermicroappsapps-lifecycles) 加载微应用的,你需要在 start 方法里配置自定义 fetch,如:
|
||||
- 如果你是通过 [registerMicroApps](/zh/api#registermicroappsapps-lifecycles) 加载微应用的,你需要在 start 方法里配置自定义 fetch,如:
|
||||
|
||||
```js
|
||||
import { start } from 'qiankun';
|
||||
|
|
@ -771,11 +768,11 @@ export async function mount(props) {
|
|||
}
|
||||
|
||||
return window.fetch(url, ...args);
|
||||
}
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
* 如果你是通过 [loadMicroApp](/zh/api#loadmicroappapp-configuration) 加载微应用的,你需要在调用时配置自定义 fetch,如:
|
||||
- 如果你是通过 [loadMicroApp](/zh/api#loadmicroappapp-configuration) 加载微应用的,你需要在调用时配置自定义 fetch,如:
|
||||
|
||||
```js
|
||||
import { loadMicroApp } from 'qiankun';
|
||||
|
|
@ -792,11 +789,11 @@ export async function mount(props) {
|
|||
}
|
||||
|
||||
return window.fetch(url, ...args);
|
||||
}
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
* 如果你是通过 [umi plugin](https://umijs.org/zh-CN/plugins/plugin-qiankun) 来使用 qiankun 的,那么你只需要给对应的微应用开启 credentials 配置即可:
|
||||
- 如果你是通过 [umi plugin](https://umijs.org/zh-CN/plugins/plugin-qiankun) 来使用 qiankun 的,那么你只需要给对应的微应用开启 credentials 配置即可:
|
||||
|
||||
```diff
|
||||
export default {
|
||||
|
|
@ -813,7 +810,3 @@ export async function mount(props) {
|
|||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ toc: menu
|
|||
# Getting Started
|
||||
|
||||
## Master Application
|
||||
|
||||
### 1. Installation
|
||||
|
||||
```bash
|
||||
|
|
@ -37,7 +38,9 @@ start();
|
|||
After the sub-application information is registered, the matching logic of the qiankun will be automatically triggered once the browser url changes, and all the render methods corresponding to the subapplications whose activeRule methods returns `true` will be called, at the same time the subapplications' exposed lifecycle hooks will be called in turn.
|
||||
|
||||
## Sub Application
|
||||
|
||||
Sub applications do not need to install any additional dependencies to integrate to qiankun master application.
|
||||
|
||||
### 1. Exports Lifecycles From Sub App Entry
|
||||
|
||||
The child application needs to export `bootstrap`,`mount`, `unmount` three lifecycle hooks in its own entry js (usually the entry js of webpack you configure) for the main application to call at the appropriate time.
|
||||
|
|
@ -66,7 +69,9 @@ export async function mount(props) {
|
|||
* usually in this case we uninstall the application instance of the subapplication.
|
||||
*/
|
||||
export async function unmount(props) {
|
||||
ReactDOM.unmountComponentAtNode(props.container ? props.container.querySelector('#root') : document.getElementById('root'));
|
||||
ReactDOM.unmountComponentAtNode(
|
||||
props.container ? props.container.querySelector('#root') : document.getElementById('root'),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ toc: menu
|
|||
# 快速上手
|
||||
|
||||
## 主应用
|
||||
|
||||
### 1. 安装 qiankun
|
||||
|
||||
```bash
|
||||
|
|
@ -41,16 +42,15 @@ start();
|
|||
```ts
|
||||
import { loadMicroApp } from 'qiankun';
|
||||
|
||||
loadMicroApp(
|
||||
{
|
||||
loadMicroApp({
|
||||
name: 'app',
|
||||
entry: '//localhost:7100',
|
||||
container: '#yourContainer',
|
||||
}
|
||||
);
|
||||
});
|
||||
```
|
||||
|
||||
## 微应用
|
||||
|
||||
微应用不需要额外安装任何其他依赖即可接入 qiankun 主应用。
|
||||
|
||||
### 1. 导出相应的生命周期钩子
|
||||
|
|
@ -77,7 +77,9 @@ export async function mount(props) {
|
|||
* 应用每次 切出/卸载 会调用的方法,通常在这里我们会卸载微应用的应用实例
|
||||
*/
|
||||
export async function unmount(props) {
|
||||
ReactDOM.unmountComponentAtNode(props.container ? props.container.querySelector('#root') : document.getElementById('root'));
|
||||
ReactDOM.unmountComponentAtNode(
|
||||
props.container ? props.container.querySelector('#root') : document.getElementById('root'),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -90,7 +92,6 @@ export async function update(props) {
|
|||
|
||||
qiankun 基于 single-spa,所以你可以在[这里](https://single-spa.js.org/docs/building-applications.html#registered-application-lifecycle)找到更多关于微应用生命周期相关的文档说明。
|
||||
|
||||
|
||||
无 webpack 等构建工具的应用接入方式请见[这里](/zh/guide/tutorial#%E9%9D%9E-webpack-%E6%9E%84%E5%BB%BA%E7%9A%84%E5%BE%AE%E5%BA%94%E7%94%A8)
|
||||
|
||||
### 2. 配置微应用的打包工具
|
||||
|
|
|
|||
|
|
@ -74,6 +74,7 @@ Take the `react 16` project generated by `create react app` as an example, with
|
|||
__webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__;
|
||||
}
|
||||
```
|
||||
|
||||
2. Set the `base` of `history` mode routing:
|
||||
|
||||
```html
|
||||
|
|
@ -115,16 +116,18 @@ Take the `react 16` project generated by `create react app` as an example, with
|
|||
4. Modify `webpack` configuration
|
||||
|
||||
Install the plugin `@rescripts/cli`, of course, you can also choose other plugins, such as `react-app-rewired`.
|
||||
|
||||
```dash
|
||||
npm i -D @rescripts/cli
|
||||
```
|
||||
|
||||
Add `.rescriptsrc.js` to the root directory:
|
||||
|
||||
```js
|
||||
const { name } = require('./package');
|
||||
|
||||
module.exports = {
|
||||
webpack: config => {
|
||||
webpack: (config) => {
|
||||
config.output.library = `${name}-[name]`;
|
||||
config.output.libraryTarget = 'umd';
|
||||
config.output.jsonpFunction = `webpackJsonp_${name}`;
|
||||
|
|
@ -133,7 +136,7 @@ Take the `react 16` project generated by `create react app` as an example, with
|
|||
return config;
|
||||
},
|
||||
|
||||
devServer: _ => {
|
||||
devServer: (_) => {
|
||||
const config = _;
|
||||
|
||||
config.headers = {
|
||||
|
|
@ -150,6 +153,7 @@ Take the `react 16` project generated by `create react app` as an example, with
|
|||
```
|
||||
|
||||
Modify `package.json`:
|
||||
|
||||
```diff
|
||||
- "start": "react-scripts start",
|
||||
+ "start": "rescripts start",
|
||||
|
|
@ -159,6 +163,7 @@ Take the `react 16` project generated by `create react app` as an example, with
|
|||
+ "test": "rescripts test",
|
||||
- "eject": "react-scripts eject"
|
||||
```
|
||||
|
||||
### Vue micro app
|
||||
|
||||
Take the `vue 2.x` project generated by `vue-cli 3+` as an example, and add it after the `vue 3` version becomes stable.
|
||||
|
|
@ -171,7 +176,7 @@ Take the `vue 2.x` project generated by `vue-cli 3+` as an example, and add it a
|
|||
}
|
||||
```
|
||||
|
||||
3. The entry file `main.js` is modified. In order to avoid the root id `#app` from conflicting with other DOMs, the search scope needs to be limited.
|
||||
2. The entry file `main.js` is modified. In order to avoid the root id `#app` from conflicting with other DOMs, the search scope needs to be limited.
|
||||
|
||||
```js
|
||||
import './public-path';
|
||||
|
|
@ -196,7 +201,7 @@ Take the `vue 2.x` project generated by `vue-cli 3+` as an example, and add it a
|
|||
instance = new Vue({
|
||||
router,
|
||||
store,
|
||||
render: h => h(App),
|
||||
render: (h) => h(App),
|
||||
}).$mount(container ? container.querySelector('#app') : '#app');
|
||||
}
|
||||
|
||||
|
|
@ -283,7 +288,7 @@ Take the `angular 9` project generated by `Angular-cli 9` as an example, other v
|
|||
async function render() {
|
||||
app = await platformBrowserDynamic()
|
||||
.bootstrapModule(AppModule)
|
||||
.catch(err => console.error(err));
|
||||
.catch((err) => console.error(err));
|
||||
}
|
||||
if (!(window as any).__POWERED_BY_QIANKUN__) {
|
||||
render();
|
||||
|
|
@ -377,12 +382,14 @@ Take the `angular 9` project generated by `Angular-cli 9` as an example, other v
|
|||
7. In order to prevent the conflict of `<app-root></app-root>` when the main app or other micro apps are also `angular`, it is recommended to add a unique id to `<app-root>`, such as Say the current app name.
|
||||
|
||||
src/index.html :
|
||||
|
||||
```diff
|
||||
- <app-root></app-root>
|
||||
+ <app-root id="angular9"></app-root>
|
||||
```
|
||||
|
||||
src/app/app.component.ts :
|
||||
|
||||
```diff
|
||||
- selector: 'app-root',
|
||||
+ selector: '#angular9 app-root',
|
||||
|
|
@ -418,6 +425,7 @@ Modify `angular.json`, `[packageName] > architect > build > builder` is the same
|
|||
- "builder": "@angular-devkit/build-angular:dev-server",
|
||||
+ "builder": "@angular-builders/dev-server:generic",
|
||||
```
|
||||
|
||||
### Micro app built without webpack
|
||||
|
||||
Some apps that are not built by `webpack`, such as `jQuery` app, `jsp` app, can be handled according to this.
|
||||
|
|
@ -452,11 +460,11 @@ example:
|
|||
|
||||
```javascript
|
||||
const render = ($) => {
|
||||
$('#purehtml-container').html("Hello, render with jQuery");
|
||||
$('#purehtml-container').html('Hello, render with jQuery');
|
||||
return Promise.resolve();
|
||||
}
|
||||
};
|
||||
|
||||
(global => {
|
||||
((global) => {
|
||||
global['purehtml'] = {
|
||||
bootstrap: () => {
|
||||
console.log('purehtml bootstrap');
|
||||
|
|
@ -464,7 +472,7 @@ example:
|
|||
},
|
||||
mount: () => {
|
||||
console.log('purehtml mount');
|
||||
return render($)
|
||||
return render($);
|
||||
},
|
||||
unmount: () => {
|
||||
console.log('purehtml unmount');
|
||||
|
|
|
|||
|
|
@ -74,6 +74,7 @@ start();
|
|||
__webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__;
|
||||
}
|
||||
```
|
||||
|
||||
2. 设置 `history` 模式路由的 `base`:
|
||||
|
||||
```html
|
||||
|
|
@ -115,16 +116,18 @@ start();
|
|||
4. 修改 `webpack` 配置
|
||||
|
||||
安装插件 `@rescripts/cli`,当然也可以选择其他的插件,例如 `react-app-rewired`。
|
||||
|
||||
```dash
|
||||
npm i -D @rescripts/cli
|
||||
```
|
||||
|
||||
根目录新增 `.rescriptsrc.js`:
|
||||
|
||||
```js
|
||||
const { name } = require('./package');
|
||||
|
||||
module.exports = {
|
||||
webpack: config => {
|
||||
webpack: (config) => {
|
||||
config.output.library = `${name}-[name]`;
|
||||
config.output.libraryTarget = 'umd';
|
||||
config.output.jsonpFunction = `webpackJsonp_${name}`;
|
||||
|
|
@ -133,7 +136,7 @@ start();
|
|||
return config;
|
||||
},
|
||||
|
||||
devServer: _ => {
|
||||
devServer: (_) => {
|
||||
const config = _;
|
||||
|
||||
config.headers = {
|
||||
|
|
@ -150,6 +153,7 @@ start();
|
|||
```
|
||||
|
||||
修改 `package.json`:
|
||||
|
||||
```diff
|
||||
- "start": "react-scripts start",
|
||||
+ "start": "rescripts start",
|
||||
|
|
@ -159,6 +163,7 @@ start();
|
|||
+ "test": "rescripts test",
|
||||
- "eject": "react-scripts eject"
|
||||
```
|
||||
|
||||
### Vue 微应用
|
||||
|
||||
以 `vue-cli 3+` 生成的 `vue 2.x` 项目为例,`vue 3` 版本等稳定后再补充。
|
||||
|
|
@ -171,7 +176,7 @@ start();
|
|||
}
|
||||
```
|
||||
|
||||
3. 入口文件 `main.js` 修改,为了避免根 id `#app` 与其他的 DOM 冲突,需要限制查找范围。
|
||||
2. 入口文件 `main.js` 修改,为了避免根 id `#app` 与其他的 DOM 冲突,需要限制查找范围。
|
||||
|
||||
```js
|
||||
import './public-path';
|
||||
|
|
@ -196,7 +201,7 @@ start();
|
|||
instance = new Vue({
|
||||
router,
|
||||
store,
|
||||
render: h => h(App),
|
||||
render: (h) => h(App),
|
||||
}).$mount(container ? container.querySelector('#app') : '#app');
|
||||
}
|
||||
|
||||
|
|
@ -283,7 +288,7 @@ start();
|
|||
async function render() {
|
||||
app = await platformBrowserDynamic()
|
||||
.bootstrapModule(AppModule)
|
||||
.catch(err => console.error(err));
|
||||
.catch((err) => console.error(err));
|
||||
}
|
||||
if (!(window as any).__POWERED_BY_QIANKUN__) {
|
||||
render();
|
||||
|
|
@ -377,12 +382,14 @@ start();
|
|||
7. 为了防止主应用或其他微应用也为 `angular` 时,`<app-root></app-root>` 会冲突的问题,建议给`<app-root>` 加上一个唯一的 id,比如说当前应用名称。
|
||||
|
||||
src/index.html :
|
||||
|
||||
```diff
|
||||
- <app-root></app-root>
|
||||
+ <app-root id="angular9"></app-root>
|
||||
```
|
||||
|
||||
src/app/app.component.ts :
|
||||
|
||||
```diff
|
||||
- selector: 'app-root',
|
||||
+ selector: '#angular9 app-root',
|
||||
|
|
@ -451,11 +458,11 @@ npm i @angular-builders/dev-server -D
|
|||
|
||||
```js
|
||||
const render = ($) => {
|
||||
$('#purehtml-container').html("Hello, render with jQuery");
|
||||
$('#purehtml-container').html('Hello, render with jQuery');
|
||||
return Promise.resolve();
|
||||
}
|
||||
};
|
||||
|
||||
(global => {
|
||||
((global) => {
|
||||
global['purehtml'] = {
|
||||
bootstrap: () => {
|
||||
console.log('purehtml bootstrap');
|
||||
|
|
@ -480,4 +487,3 @@ npm i @angular-builders/dev-server -D
|
|||
### umi-qiankun 项目
|
||||
|
||||
`umi-qiankun` 的教程请移步 [umi 官网](https://umijs.org/zh-CN/plugins/plugin-qiankun) 和 [umi-qiankun 的官方 demo](https://github.com/umijs/umi-plugin-qiankun/tree/master/examples)
|
||||
|
||||
|
|
|
|||
|
|
@ -80,7 +80,7 @@
|
|||
"husky": "^2.3.0",
|
||||
"jest": "^25.2.2",
|
||||
"levenary": "^1.1.1",
|
||||
"lint-staged": "^9.4.2",
|
||||
"lint-staged": "^10.5.4",
|
||||
"np": "^5.0.3",
|
||||
"npm-run-all": "^4.1.5",
|
||||
"prettier": "^2.1.2",
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user