需要开发的功能点
1.应用加载
根据注册的子应用,通过给定的url,加载约定格式的子应用入口,并挂载到给定位置。入口方式通常有两种:HTML和JS,JS做入口更纯粹,HTML做入口更易于旧项目改造。此外,提供预加载功能也很有必要,预加载是指在应用尚未渲染时提前加载资源并缓存,从而提升首屏渲染速度。
2.生命周期
3.路由同步
子应用的路由切换时,同步更新url;url改变时,同步更新子应用。
4.应用通信
5.沙箱隔离
(1)JS隔离
- Snapshot。子应用挂载时,先对全局window变量打个快照放闭包里,再把全局window交给子应用,在子应用卸载时通过快照恢复全局window变量。这种方式实际上并没有形成“隔离”,只是防止多个子应用互相“污染”,并且多个子应用之间不能共存,因为全局window只有一个,快照只有一个。
- Sandbox
- Wasm VM。重新编译一个Wasm(WebAssembly)的JS解释器放在浏览器中,把子应用直接放进这个VM中执行,这种方式隔离非常严格,通信开销非常大。
- with()+new Function(code)+Proxy。with语法用于改变作用域链,当访问全局变量时进行拦截,不对window进行查找。new Function()将一段字符串解析成一段JS脚本并执行,只能访问全局作用域。Proxy提供的是with和new Function闭包中用到的充当window作用域的对象,通过白名单属性限制能访问真正window上的部分元素,同时对document、history、location进行劫持限制等,从而组成沙箱环境。
(2)CSS隔离:命名约定、自动Scope、Shadow DOM、自动卸载、弹窗遮罩。
6.异常处理
插入点
- 通过 Loader 核心模块支持 HTML entry、JS entry 的支持,接入微前端应用简单易用
- Router 模块提供了路由驱动、主子路由隔离,用户仅需要配置路由表应用即可完成自主的渲染和销毁,无需关心内部逻辑
Sandbox 模块为应用的 Runtime 提供运行时隔离能力,能有效隔离 JS、Style 对应用的副作用影响
使用总结
使用 Garfish API 搭建一套微前端主子应用的主要成本来自两方面
主应用的搭建
- 注册子应用的基本信息
- 使用 Garfish 在主应用上调度管理子应用
- 子应用的改造
- 增加对应的构建配置
- 使用 @garfish/bridge 包提供的函数包装子应用后返回 provider 函数并导出
- 子应用针对不同的框架类型,添加不同 basename 的设置方式
- React 在根组件中获取 basename 将其传递至 BrowserRouter 的 basename 属性中
- Vue 将 basename 传递至 VueRouter 的 basename 属性中
