📝 add faq about how to make global event listener works well (#2734)

This commit is contained in:
Bravepg 2023-10-19 23:08:16 -05:00 committed by GitHub
parent 3e133bdc27
commit 46e492156e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 85 additions and 36 deletions

View File

@ -35,10 +35,10 @@ To solve the exception, try the following steps:
8. If you are using webpack5 and using module federation, you need to expose the life cycle function in the index file, and then expose the life cycle function externally in the bootstrap file.
```js
const promise = import("index");
export const bootstrap = () => promise.then(m => m.bootstrap());
export const mount = () => promise.then(m => m.mount());
export const unmount = () => promise.then(m => m.unmount());
const promise = import('index');
export const bootstrap = () => promise.then((m) => m.bootstrap());
export const mount = () => promise.then((m) => m.mount());
export const unmount = () => promise.then((m) => m.unmount());
```
9. Check whether the main app and micro-app use AMD or CommonJS. Check method: run the main app and the micro-app independently, and enter the following code in the console: `(typeof exports === 'object' && typeof module === 'object') || (typeof define === 'function' && define.amd) || typeof exports === 'object'`If it returns `true`that it is caused by this reason, and there are mainly the following two solutions:
@ -56,6 +56,7 @@ To solve the exception, try the following steps:
},
};
```
- Solution 2: The micro-app is not bundle with `umd`, directly mount the life cycle function to the `window` in the entry file, refer to[Micro app built without webpack](/guide/tutorial#micro-app-built-without-webpack).
10. 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:
@ -150,7 +151,9 @@ How to determine the completion of the container DOM loading? The vue app can be
If it still reports an error, check whether the container DOM is placed on a routing page of the main app, please refer to [How to load micro apps on a routing page of the main app](#How to load micro apps on a routing page of the main app)
## `[import-html-entry]: error occurs while excuting xxx script http://xxx.xxx.xxx/x.js`
![](https://user-images.githubusercontent.com/22413530/109919189-41563d00-7cf3-11eb-8328-711228389d63.png)
The first line is just a helper info printed by qiankun via `console.error` to help users identify which js file threw the error faster. It is not an exception thrown by qiankun itself.
**The actual exception info is in the second line.**
@ -158,6 +161,7 @@ The first line is just a helper info printed by qiankun via `console.error` to h
For example in the error above, it means the child app itself threw an exception when executing http://localhost:9100/index.bundle.js. **And the actual exception message is `Uncaught TypeError: Cannot read property 'call' of undefined` in the second line.**
Exceptions from the child app itself can be debugged and fixed with the following steps:
1. Based on the specific exception message, check if the js file that errors has syntax errors, like missing semicolons, depending on uninitialized variables etc.
2. Whether it depends on global variables provided by the main app, but the main app did not initialize them.
3. Compatibility issues. The child app js itself has syntax compatibility issues in the current runtime environment.
@ -261,6 +265,8 @@ To solve the error, choose one of the options listed below:
## Why dynamic imported assets missing?
The reason is that webpack does not use the correct `publicPath` when loading the resource.
Two way to solve that:
### 1. With webpack live public path config
@ -508,6 +514,8 @@ Yes it is.
Since qiankun get assets which imported by sub app via fetch, these static resources must be required to support [cors](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS).
If it is your own script, you can support it by developing server-side cross-domain. If it is a 3-legged script and cannot add cross-domain headers to it, you can drag the script to the local and have your own server serve support cross-domain.
See [Enable Nginx Cors](https://enable-cors.org/server_nginx.html).
## How to solve that micro apps loaded failed due to abnormal scripts inserted dynamically by carriers
@ -682,6 +690,10 @@ import 'core-js/web/url';
**We recommend that you use @babel/preset-env plugin directly to polyfill IE automatically, all the instructions for @babel/preset-env you can found in [babel official document](https://babeljs.io/docs/en/babel-preset-env).**
<Alert type="info">
You can also check out<a href="https://www.yuque.com/kuitos/gky7yw/qskte2" target="_blank">this article</a>to learn more about IE compatibility.
</Alert>
## Error `Here is no "fetch" on the window env, you need to polyfill it`
Qiankun use `window.fetch` to get resources of the micro applications, but [some browsers does not support it](https://caniuse.com/#search=fetch), you should get the [polyfill](https://github.com/github/fetch) in the entry.
@ -832,3 +844,29 @@ As the requests to pull micro-app entry are all cross-domain, when your micro-ap
},
});
```
- If you are through [umi plugin](https://umijs.org/zh-CN/plugins/plugin-qiankun) to use qiankunthen you only need to enable the credentials configuration for the corresponding microapp:
```diff
export default {
qiankun: {
master: {
apps: [
{
name: 'app',
entry: '//app.alipay.com/entry.html',
+ credentials: true,
}
]
}
}
}
```
## How to solve the problem that adding event handlers to window objects by subapplication does not take effect
Since the window object accessed by the sub-application is the object after being proxed by qiankun, it is invalid to add an event handler directly to the window object, and you can solve the problem by adding an event listener to the window by addEventListener:
```js
window.addEventListener('eventName', eventHandler);
```

View File

@ -35,10 +35,10 @@ qiankun 抛出这个错误是因为无法从微应用的 entry js 中识别出
8. 如果你正在使用 webpack5并且使用了使用模块联邦。需要在 index 文件中暴露生命周期函数,然后在 bootstrap 文件向外暴露生命周期函数。
```js
const promise = import("index");
export const bootstrap = () => promise.then(m => m.bootstrap());
export const mount = () => promise.then(m => m.mount());
export const unmount = () => promise.then(m => m.unmount());
const promise = import('index');
export const bootstrap = () => promise.then((m) => m.bootstrap());
export const mount = () => promise.then((m) => m.mount());
export const unmount = () => promise.then((m) => m.unmount());
```
9. 检查主应用和微应用是否使用了 AMD 或 CommonJS 模块化。检查方法:单独运行微应用和主应用,在控制台输入如下代码:`(typeof exports === 'object' && typeof module === 'object') || (typeof define === 'function' && define.amd) || typeof exports === 'object'`,如果返回 `true`,则说明是这种情况,主要有以下两个解决办法:
@ -56,8 +56,8 @@ qiankun 抛出这个错误是因为无法从微应用的 entry js 中识别出
},
};
```
- 解决办法2微应用不打包成 umd ,直接在入口文件把生命周期函数挂载到 window 上,参考[非 webpack 构建的微应用](/zh/guide/tutorial#非-webpack-构建的微应用)。
- 解决办法 2微应用不打包成 umd ,直接在入口文件把生命周期函数挂载到 window 上,参考[非 webpack 构建的微应用](/zh/guide/tutorial#非-webpack-构建的微应用)。
10. 如果在上述步骤完成后仍有问题,通常说明是浏览器兼容性问题导致的。可以尝试 **将有问题的微应用的 webpack `output.library` 配置成跟主应用中注册的 `name` 字段一致**,如:
@ -151,6 +151,7 @@ qiankun 抛出这个错误是因为微应用加载后容器 DOM 节点不存在
如果仍然报错,检查容器 DOM 是否放在了主应用的某个路由页面,请参考[如何在主应用的某个路由页面加载微应用](#如何在主应用的某个路由页面加载微应用)。
## `[import-html-entry]: error occurs while excuting xxx script http://xxx.xxx.xxx/x.js`
![](https://user-images.githubusercontent.com/22413530/109919189-41563d00-7cf3-11eb-8328-711228389d63.png)
其中第一行只是 qiankun 通过 `console.error` 打印出来的一个辅助信息,目的是帮助用户更快的知道是哪个 js 报错了,并不是 qiankun 本身发生了异常。
@ -160,6 +161,7 @@ qiankun 抛出这个错误是因为微应用加载后容器 DOM 节点不存在
比如上图这样一个报错,指的是子应用在执行 `http://localhost:9100/index.bundle.js` 时,这个 js 本身抛异常了。**而具体的异常信息就是第二行的 `Uncaught TypeError: Cannot read property 'call' of undefined`。**
子应用本身的异常,可以尝试通过以下步骤排查解决:
1. 根据具体的异常信息,检查报错的 js 是否有语法错误,比如少了分号、依赖了未初始化的变量等。
2. 是否依赖了主应用提供的全局变量,但实际主应用并未初始化。
3. 兼容性问题。子应用这个 js 本身在当前运行环境存在语法兼容性问题。
@ -638,6 +640,7 @@ export const mount = async () => render();
```js {2,3,7}
registerMicroApps([
// 自定义 activeRule
{ name: 'reactApp', entry: '//localhost:7100', container, activeRule: () => isReactApp() },
{ name: 'react15App', entry: '//localhost:7102', container, activeRule: () => isReactApp() },
{ name: 'vueApp', entry: '//localhost:7101', container, activeRule: () => isVueApp() },
@ -859,3 +862,11 @@ export async function mount(props) {
}
}
```
## 如何解决子应用给 window 对象添加事件处理函数不生效的问题
由于子应用访问的 window 对象是被 qiankun 代理后的对象,因此直接给 window 对象添加事件处理函数是无效的,可以通过 addEventListener 给 window 添加事件监听器来解决该问题:
```js
window.addEventListener('eventName', eventHandler);
```