微前端
将不同的功能按照不同的维度拆分成多个子应用。通过主应用加载子应用。类似于 iframe
应用之间通信
- 基于URL进行数据传递
- 基于CustomEvent 实现通信
- 基于props主从
- 全局变量、Redux
主子应用资源隔离
样式隔离
- 动态样式表
- BEM约定项目前缀
- CSS-modules 打包生成不冲突类名
- Shadow Dom 真正意义上的隔离
Shadow Dom 示例:
let shadowDom =$('#shawdow').attachShadow({mode: 'closed})
shadoweDom.append(style)
shadoweDom,append(pDom)
JS沙箱
快照沙箱:
记录window上属性的变化。当激活时重新赋值。
缺点:不利于多应用
ES6 代理沙箱(proxy):
可创建多个Proxy代理实例。利于多个子应用沙箱处理。
Single-SPA
用于前端微服务化的js前端解决方案。实现了路由劫持和应用加载。打包成lib。
特点:
- 本身没有处理样式隔离,js执行隔离。
- 不能动态加载子应用js文件,不够灵活
- 子应用必须导出bootstrap、mount、unmount方法
子应用(npm i single-spa-vue、single-spa-react)
设置打包类型为 :umd
- 引用:
import singleSpaVue from 'single-spa-vue'
- 实例子应用:
const vueLife = singleSpaVue({Vue,appOptions: {
el: '#vue' ,(挂载主应用id)
router,
render: h => h(App)
}})
- 导出子应用生命周期:
export const bootstrap = vueLife.bootstrap
export const mount = vueLife.mount
export const unmount = vueLife.unmount
主应用(npm i single-spa)
通过加载(script.src)子应用chunk-vendors.js、app.js,显示在指定el(子应用实例上的el) ;
registerApplication中加载aync方法中必须是个异步加载js文件(return new promise());路由使用 mode: 'history',
- 导入:
import { start, registerApplication} from single-spa
- 注册:
registerApplication(
'MyApp',
async ()=> {
// 加载子应用js文件, 并且return 子应用的三个生命周期
return window.singleVue
},
location => {
// 拦截路由
}
)
- 执行: start()
qiankun(基于Single-SPA)
特点
- 本身处理样式隔离,js执行隔离。
- 动态加载子应用js文件,灵活
子应用(webpack设置打包结果为umd(必须);路由使用 mode: 'history')
- 导出子应用生命周期:
export async function bootstrap(proprs){}
export async function mount (proprs){}
export async function unmount (proprs){}
- 设置子应用独立运行时:
if(!window.__POWERED_BY_QIANKUN){
render()
}
- 设置子应用在主应用运行时:
if (window.__POWERED_BY_QIANKUN__){
__webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN
}
- webpack设置可跨域(必须):
....
devServer: {
port: 1000,
headers: {
'Access-Control-Allow-Origin': '*'
}
}
主应用(npm i qiankun)
- 页面设置宿主Dom:
<div id="vue"></div>
2.导入:
import { registerMicroApps, start } from 'qiankun'
- 注册应用并开启:
const apps = [
{
name:'vueApp', // 应用名字
entry: '//localhost:10000', // 子应用访问地址
container: '#vue', // 宿主DOM id
activeRule: '/vue', // 路由
}
]
registerMicroApps(apps)
start({})