微前端Single-SPA与qiankun(基于Single-SPA)

Scroll Down

微前端

将不同的功能按照不同的维度拆分成多个子应用。通过主应用加载子应用。类似于 iframe

应用之间通信

  1. 基于URL进行数据传递
  2. 基于CustomEvent 实现通信
  3. 基于props主从
  4. 全局变量、Redux

主子应用资源隔离

样式隔离

  1. 动态样式表
  2. BEM约定项目前缀
  3. CSS-modules 打包生成不冲突类名
  4. 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。

特点:

  1. 本身没有处理样式隔离,js执行隔离。
  2. 不能动态加载子应用js文件,不够灵活
  3. 子应用必须导出bootstrap、mount、unmount方法

子应用(npm i single-spa-vue、single-spa-react)

设置打包类型为 :umd

  1. 引用:
 import singleSpaVue from 'single-spa-vue'
  1. 实例子应用:
const vueLife = singleSpaVue({Vue,appOptions: {
el: '#vue' ,(挂载主应用id)
router,
render: h => h(App)
}})
  1. 导出子应用生命周期:
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',

  1. 导入:
import { start, registerApplication} from single-spa
  1. 注册:
registerApplication(
'MyApp',
async ()=> {
   // 加载子应用js文件, 并且return 子应用的三个生命周期
   return window.singleVue
 },
   location => {
 // 拦截路由
   }
)
  1. 执行: start()

qiankun(基于Single-SPA)

特点

  1. 本身处理样式隔离,js执行隔离。
  2. 动态加载子应用js文件,灵活

子应用(webpack设置打包结果为umd(必须);路由使用 mode: 'history')

  1. 导出子应用生命周期:
export  async  function bootstrap(proprs){}
export async  function  mount (proprs){}
export async  function unmount (proprs){}
  1. 设置子应用独立运行时:
if(!window.__POWERED_BY_QIANKUN){
  render()
}
  1. 设置子应用在主应用运行时:
if (window.__POWERED_BY_QIANKUN__){
   __webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN
}
  1. webpack设置可跨域(必须):
....
devServer: {
  port: 1000,
headers: {
  'Access-Control-Allow-Origin': '*'
}
}

主应用(npm i qiankun)

  1. 页面设置宿主Dom:
<div id="vue"></div>

2.导入:

import { registerMicroApps, start } from 'qiankun'
  1. 注册应用并开启:
const apps = [
   {
 name:'vueApp', // 应用名字
 entry: '//localhost:10000', // 子应用访问地址
container: '#vue', // 宿主DOM id
   activeRule: '/vue', // 路由
   }
]
registerMicroApps(apps)
start({})