Skip to content

Commit

Permalink
docs: 完善umd相关文档&demo代码优化
Browse files Browse the repository at this point in the history
  • Loading branch information
bailicangdu committed Sep 7, 2021
1 parent e38b41a commit eab2c17
Show file tree
Hide file tree
Showing 9 changed files with 122 additions and 55 deletions.
4 changes: 2 additions & 2 deletions docs/sidebar.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@
- [预加载](zh-cn/prefetch)
- [插件系统](zh-cn/plugins)
- [多层嵌套](zh-cn/qiantao)
- [高级功能](zh-cn/advanced)
- [查看版本](zh-cn/version)
- [高级功能](zh-cn/advanced)
- [路由](zh-cn/route)
- [部署](zh-cn/deploy)
<!-- - [部署](zh-cn/deploy) -->

- 其他

Expand Down
83 changes: 83 additions & 0 deletions docs/zh-cn/advanced.md
Original file line number Diff line number Diff line change
Expand Up @@ -144,3 +144,86 @@ microApp.start({
> 3、请确保vite版本>=2.5.0

## 3、内存优化
虽然我们在卸载子应用时对变量和事件进行了清除,但仍有一些变量无法回收。

如果子应用渲染和卸载非常频繁,建议通过下面方式进行内存优化。

### 子应用
#### 1、在入口文件导出相应的生命周期钩子

<!-- tabs:start -->

#### ** React **
```js
// index.js
...
// 应用每次渲染时都会执行 mount 方法,在此处可以执行初始化相关操作(必传)
export function mount () {
ReactDOM.render(<App />, document.getElementById("root"))
}

// 应用每次卸载时都会执行 unmount 方法,在此处可以执行卸载相关操作(必传)
export function unmount () {
// 卸载应用
ReactDOM.unmountComponentAtNode(document.getElementById("root"));
}

```

#### ** Vue **
```js
// main.js
...
let app
// 应用每次渲染时都会执行 mount 方法,在此处可以执行初始化相关操作(必传)
export function mount () {
app = new Vue({
router,
render: h => h(App),
}).$mount('#app')
}

// 应用每次卸载时都会执行 unmount 方法,在此处可以执行卸载相关操作(必传)
export function unmount () {
// 卸载应用
app.$destroy()
}

```
<!-- tabs:end -->

#### 2、修改webpack配置
```js
// webpack.config.js
module.exports = {
...
output: {
library: 'micro-app-子应用的name', // 子应用的name就是<micro-app name='xxx'></micro-app>中name属性的值
libraryTarget: 'umd',
jsonpFunction: `webpackJsonp_${packageName}`,
},
}
```

通常`library`的值固定为`micro-app-子应用的name`,但也可以自定义,此时需要在`<micro-app></micro-app>`标签中通过`library`属性指定名称。

```js
// webpack.config.js
module.exports = {
...
output: {
library: '自定义的library名称',
libraryTarget: 'umd',
jsonpFunction: `webpackJsonp_${packageName}`,
},
}
```

```html
<micro-app
name='xxx'
url='xxx'
library='自定义的library名称'
></micro-app>
```
3 changes: 3 additions & 0 deletions docs/zh-cn/questions.md
Original file line number Diff line number Diff line change
Expand Up @@ -150,3 +150,6 @@ microApp.start({
如:`fetch('/api/data')`,在请求时会自动被浏览器补全为`fetch('基座域名/api/data')`

为了避免这个问题,子应用需要使用完整的地址:`fetch('子应用域名/api/data')`

## 15、子应用多次渲染后内存越来越大
参考[内存优化](/zh-cn/advanced?id=_3、内存优化)一章
48 changes: 21 additions & 27 deletions examples/children/react16/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,9 @@ window.microApp?.addDataListener((data) => {
}, true)

function handleGlobalData(data) {
console.log(222222, 'react16: 来全局数据')
console.log('react16: 来自全局数据')
Modal.info({
title: "react16: 来全局数据",
title: "react16: 来自全局数据",
content: (
<div>
<p>{JSON.stringify(data)}</p>
Expand All @@ -47,29 +47,27 @@ window.microApp?.addGlobalDataListener(handleGlobalData);
// document.getElementById("root")
// );

// 监听卸载
window.addEventListener("unmount", function () {
// microApp.clearApps()
console.log("微应用react16卸载了");
// 卸载前卸载全局数据监听
// window.microApp?.removeGlobalDataListener(handleGlobalData);
// 卸载应用
ReactDOM.unmountComponentAtNode(document.getElementById("root"));
})
// // 监听卸载
// window.addEventListener("unmount", function () {
// // microApp.clearApps()
// console.log("微应用react16卸载了");
// // 卸载前卸载全局数据监听
// // window.microApp?.removeGlobalDataListener(handleGlobalData);
// // 卸载应用
// ReactDOM.unmountComponentAtNode(document.getElementById("root"));
// })

console.timeEnd("react16");
// document.addEventListener('click', function () {
// console.log(`子应用${window.__MICRO_APP_NAME__}内部的document.addEventListener(click)绑定`)
// }, false)

document.addEventListener('click', function () {
console.log(`子应用${window.__MICRO_APP_NAME__}内部的document.addEventListener(click)绑定`)
}, false)
// document.onclick = () => {
// console.log(`子应用${window.__MICRO_APP_NAME__}内部的document.onclick绑定`)
// }

document.onclick = () => {
console.log(`子应用${window.__MICRO_APP_NAME__}内部的document.onclick绑定`)
}

window.addEventListener('scroll', () => {
console.log(`scroll event from ${window.__MICRO_APP_NAME__}`)
}, false)
// window.addEventListener('scroll', () => {
// console.log(`scroll event from ${window.__MICRO_APP_NAME__}`)
// }, false)

// setInterval(() => {
// console.log(`子应用${window.__MICRO_APP_NAME__}的setInterval`)
Expand All @@ -83,7 +81,7 @@ export function mount () {
</React.StrictMode>,
document.getElementById("root")
);
window.ccc = 2222
console.timeEnd("react16");
}

export function unmount () {
Expand All @@ -93,7 +91,3 @@ export function unmount () {
// 卸载应用
ReactDOM.unmountComponentAtNode(document.getElementById("root"));
}

console.log(555555555555)

window.aaa = 1111
2 changes: 1 addition & 1 deletion examples/children/react16/src/pages/inline/inline.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ function Vue2 () {
const [showLoading, hideLoading] = useState(true)
return (
<div>
<div>子应用内嵌其它子应用</div>
<h3>子应用多层嵌套</h3>
<div className='btn-con'>
<Button
type='primary'
Expand Down
16 changes: 7 additions & 9 deletions examples/children/vue2/src/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,20 +25,19 @@ let app
// render: h => h(App),
// }).$mount('#app')

// 监听卸载
window.addEventListener('unmount', function () {
console.log('微应用vue2卸载了')
// 卸载应用
app.$destroy()
})
// // 监听卸载
// window.addEventListener('unmount', function () {
// console.log('微应用vue2卸载了')
// // 卸载应用
// app.$destroy()
// })

console.log(6666666666)
export function mount () {
console.log(4444444444)
app = new Vue({
router,
render: h => h(App),
}).$mount('#app')
console.timeEnd('vue2')
}

export function unmount () {
Expand All @@ -47,4 +46,3 @@ export function unmount () {
app.$destroy()
}

console.timeEnd('vue2')
5 changes: 2 additions & 3 deletions examples/main-react16/src/pages/react16/react16.js
Original file line number Diff line number Diff line change
Expand Up @@ -118,8 +118,7 @@ export default class App extends React.Component {

componentWillUnmount () {
microApp.clearDataListener('react16')
// microApp.removeGlobalDataListener(this.handleGlobalDataForBaseApp)
microApp.clearGlobalDataListener()
microApp.removeGlobalDataListener(this.handleGlobalDataForBaseApp)
}

render () {
Expand Down Expand Up @@ -172,7 +171,7 @@ export default class App extends React.Component {
name='modal-app1'
url={this.state.url}
baseurl='/micro-app/demo/react16'
inline
library='micro-app-react16'
// disableSandbox
// macro
/>
Expand Down
11 changes: 0 additions & 11 deletions examples/main-react16/src/pages/vue2/vue2.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import { Button, Spin } from 'antd'
import { LoadingOutlined } from '@ant-design/icons'
import config from '../../config'
import './vue2.less'
import microApp from '@micro-zoe/micro-app'

const antIcon = <LoadingOutlined style={{ fontSize: 30 }} spin />

Expand All @@ -15,9 +14,6 @@ function Vue2 () {
const [showLoading, hideLoading] = useState(true)
useEffect(() => {
console.time('vue2')
microApp.addGlobalDataListener((data) => {
console.log('这是全局数据--基座vue2', data)
})
}, [])
return (
<div>
Expand All @@ -29,13 +25,6 @@ function Vue2 () {
>
发送数据
</Button>
<Button
type='primary'
onClick={() => microApp.setGlobalData({name: '全局数据' + (+new Date())})}
style={{width: '120px'}}
>
发送全局数据
</Button>
</div>
{
showLoading && <Spin indicator={antIcon} />
Expand Down
5 changes: 3 additions & 2 deletions src/create_app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,8 @@ export default class CreateApp implements AppInterface {
)
// Send an unmount event to the micro app or call umd unmount hook
// before the sandbox is cleared & after the unmount lifecycle is executed
this.umdHookunMount ? this.umdHookunMount() : dispatchUnmountToMicroApp(this.name)
this.umdHookunMount && this.umdHookunMount()
dispatchUnmountToMicroApp(this.name)
this.sandBox?.stop()
this.container = null
if (destory) {
Expand Down Expand Up @@ -217,7 +218,7 @@ export default class CreateApp implements AppInterface {
if (appStatus.UNMOUNT !== this.status) {
const global = (this.sandBox?.proxyWindow ?? rawWindow) as any
const libraryName = (this.container instanceof ShadowRoot ? this.container.host : this.container)!.getAttribute('library') || `micro-app-${this.name}`
return toString.call(global[libraryName]) === '[object Object]' ? global[libraryName] : {}
return typeof global[libraryName] === 'object' ? global[libraryName] : {}
}

return {}
Expand Down

0 comments on commit eab2c17

Please sign in to comment.