早早聊 C7 笔记 - 【字节】时光:微前端沙盒体系的落地实践

# 拆分维度

  • Code Splitting
    • dynamic import
      • react-lazy(react-loadable)
    • webpack 4.0
      • Named chunk
  • Runtime Splitting
    • Iframe
    • sandbox
  • Deployment Splitting

# 沙盒应该做什么

古老的 iframe —— 古老的困难

  • 一些能做的
    • 一个站点页面拆成 N 个 frame
    • 每个 frame 单独一个独立域名
    • 独立上下线
    • 独立运行时
  • 困难
    • 难以 deeplinking
    • 数据共用困难
      • 登录身份
      • 站内信
      • 跨模块通信
    • 困难重重的共用代码、加载优化、运行优化

# 沙盒像什么

  • Docker
    • 开发者必须体会不到环境的区别
    • 运行时没有环境差异
    • 服务端微服务的基石
  • Docker 时代之前的(服务端)微服务
    • 虚拟机使用复杂,维护成本巨大
      • 资源消耗
      • 镜像启动
      • 进程通信
    • 直到 Docker 普及
    • 前端的“微服务”在浏览器环境下并没有
  • 微前端的实践
    • 前端沙盒像浏览器里面的 Docker
    • Iframe 像虚拟机

# 沙盒怎么做

  • 参考单核、操作系统进程模拟进程切换策略
    • JavaScript 是单线程的
    • 通过对路由切换的封装,模拟单进程
    • 通过对事件循环封装,模拟单核多进程
  • 用 Context 切换模拟线程安全
    • 新沙盒即将激活时,查找当前激活中的沙盒
    • 保存现场,存储 Context
    • 恢复之前的 Context
  • Context 切换的笛卡尔积
    • 比较并切换
    • 沙盒数量 N 的笛卡尔平方
    • 退回“初始” Context
    • 恢复之前 diff 的 Context

# 字节的沙盒做了什么

# CSS 的干扰

  • 独立开发、混合加载
    • HTML 标准的 CSS 作用域
    • Scoped CSS
    • Shadow DOM
  • CSS module、CSS in JavaScript
    • DOM header
  • 单核多进程的情况
    • 多个沙盒时,只能 CSS in JavaScript
  • CSSStyleSheet.cssRules

# 全局变量的干扰

  • Polyfill 等差异巨大
    • 如 generatorRuntime
    • 组件模块化
    • 全局的外部环境
  • Identifier
    • let
    • const
    • class
  • Configurable
  • window.location

# 需要进程安全的对象

  • DOM 沙盒等
  • Cookie
  • LocalStorage

# 沙盒模式中埋点、系统采样的设计

# 埋点数据的缓存创建

  • 全局数据(uid 等)默认缓存本地
  • 缓存跟随沙盒切换
  • 两级缓存
    • 沙箱内全局
    • 系统全局

# 埋点数据的发送

  • 异步发送
  • 触发时机在沙盒外、缓存跟随沙盒切换
  • 全局缓存和本地缓存统一本地存储

# console 回收

  • 干净体面
  • 控制 sourceMapping
  • 向 log 中注入 callstack
  • 额外加入快照

# sourceMapping

  • 原理:文本的映射
  • new Function
  • 管理发布