micro-app 官网 https://jd-opensource.github.io/micro-app/docs.html#/
项目搭建
https://blog.csdn.net/weixin_41192489/article/details/143164336
路由
https://blog.csdn.net/weixin_41192489/article/details/145034614
生命周期
https://blog.csdn.net/weixin_41192489/article/details/145038406
通信
https://blog.csdn.net/weixin_41192489/article/details/145051057
原理解析
JS 隔离
通过自定义的window、document拦截子应用的JS操作,实现一个相对独立的运行空间,避免全局变量污染,让每个子应用都拥有一个相对纯净的运行环境。
样式隔离
以<micro-app>
标签作为样式作用域,利用标签的name属性为每个样式添加前缀,将子应用的样式影响禁锢在当前标签区域。
.test {
color: red;
}
/* 转换为 */
micro-app[name=xxx] .test {
color: red;
}
元素隔离
micro-app模拟实现了类似ShadowDom的功能,元素不会逃离<micro-app>
元素边界
- 子应用只能操作自身的元素
- 主应用可操作子应用元素
资源路径自动补全
子应用中相对地址的资源会自动补全路径,如
子应用中引用图片/myapp/test.png,在最终渲染时会补全为http://localhost:8080/myapp/test.png
子应用常用操作
判断是否在微前端环境中
if (window.__MICRO_APP_ENVIRONMENT__) {
console.log('我在微前端环境中')
}
获取应用的name值
window.__MICRO_APP_NAME__
判断当前应用是否是主应用
if (window.__MICRO_APP_BASE_APPLICATION__) {
console.log('我是主应用')
}
获取真实window
默认情况下子应用window指向代理对象,通过rawWindow可以获取真实window。
window.rawWindow
获取真实document
默认情况下子应用document指向代理对象,通过rawDocument可以获取真实document。
window.rawDocument
资源过滤
方式1 – excludeAssetFilter
在start中注册excludeAssetFilter过滤函数,可以指定部分特殊的动态加载的微应用资源(css/js) 不被 micro-app 劫持处理。
// index.js
import microApp from '@micro-zoe/micro-app'
microApp.start({
excludeAssetFilter (assetUrl) {
if (assetUrl === 'xxx') {
return true // 返回true则micro-app不会劫持处理当前文件
}
return false
}
})
方式2 – 配置 exclude 属性
在link、script、style等元素上设置exclude属性过滤这些资源,当micro-app遇到带有exclude属性的元素会进行删除。
<link rel="stylesheet" href="xx.css" exclude>
<script src="xx.js" exclude></script>
<style exclude></style>
keep-alive模式
在应用之间切换时,保留这些应用的状态,以便恢复用户的操作行为和提升重复渲染的性能。
开启keep-alive后,应用卸载时不会销毁,而是推入后台运行。
<micro-app name='xx' url='xx' keep-alive></micro-app>
开启keep-alive后,生命周期的变化和对 appstate-change 事件的监听方法详见官网
应用嵌套
如子应用A嵌套子应用B,子应用B嵌套子应用C
- 无论嵌套多少层,name都要保证全局唯一
步骤1
在B应用中自定义tagName
import microApp from '@micro-zoe/micro-app';
microApp.start({
// 必须是以`micro-app-`开头的小写字母,例如:micro-app-b、micro-app-b-c
tagName: 'micro-app-xxx',
})
在B中使用新定义的标签加载C
<micro-app-xxx name='...' url='...'></micro-app-xxx>
步骤2
将B应用切换为umd模式
禁用样式隔离
https://blog.csdn.net/weixin_41192489/article/details/145049601
自定义fetch
通过自定义fetch替换框架自带的fetch,可以修改fetch配置(添加cookie或header信息等等),或拦截HTML、JS、CSS等静态资源。
自定义的fetch必须是一个返回string类型的Promise。
如果跨域请求带cookie,那么Access-Control-Allow-Origin不能设置为*,必须指定域名,同时设置Access-Control-Allow-Credentials: true
import microApp from '@micro-zoe/micro-app'
microApp.start({
/**
* 自定义fetch
* @param {string} url 静态资源地址
* @param {object} options fetch请求配置项
* @param {string|null} appName 应用名称
* @returns Promise<string>
*/
fetch (url, options, appName) {
if (url === 'http://localhost:3001/error.js') {
// 删除 http://localhost:3001/error.js 的内容
return Promise.resolve('')
}
const config = {
// fetch 默认不带cookie,如果需要添加cookie需要配置credentials
credentials: 'include', // 请求时带上cookie
}
return window.fetch(url, Object.assign(options, config)).then((res) => {
return res.text()
})
}
})
性能优化
预加载
- 预加载即在子应用尚未渲染时提前加载静态资源,从而提升子应用的首次渲染速度。
- 预加载会在浏览器空闲时间执行
详见官网
资源共享
当多个子应用拥有相同的js或css资源,可以指定这些资源在多个子应用之间共享,在子应用加载时直接从缓存中提取数据,从而提高渲染效率和性能。
方式1 – globalAssets
用于设置全局共享资源,它和预加载的思路相同,在浏览器空闲时加载资源并放入缓存。
// index.js
import microApp from '@micro-zoe/micro-app'
microApp.start({
globalAssets: {
js: ['js地址1', 'js地址2', ...], // js地址
css: ['css地址1', 'css地址2', ...], // css地址
}
})
方式2 – global 属性
在link、script设置global属性会将文件提取为公共文件,共享给其它应用。
设置global属性后文件第一次加载会放入公共缓存,其它子应用加载相同的资源时直接从缓存中读取内容,从而提升渲染速度。
<link rel="stylesheet" href="xx.css" global>
<script src="xx.js" global></script>
开启 umd 模式
- 默认模式:子应用在初次渲染和后续渲染时会顺序执行所有js,以保证多次渲染的一致性。
- umd模式:子应用暴露出mount、unmount方法,此时只在初次渲染时执行所有js,后续渲染只会执行这两个方法,在多次渲染时具有更好的性能和内存表现。
推荐使用umd模式,以获得更好的性能和内存表现,默认模式更适合渲染和卸载不频繁的子应用。
开启方式详见官网
插件系统
详见官网
部署
https://jd-opensource.github.io/micro-app/docs.html#/zh-cn/deploy
调试插件 Micro-App-DevTools
https://jd-opensource.github.io/micro-app/docs.html#/zh-cn/micro-app-devtools
常见问题
资源路径自动补全失效
原因:一些框架和库在特定场景下创建的元素无法被拦截和处理,或者当关闭样式隔离和沙箱时,也会导致自动补全失效。
解决方案:publicPath