weixin_39618169
2020-11-23 02:59 阅读 16

[RFC] icestark@2.0 版本设计

目标

  • 框架应用支持 Vue 等其他框架,不再限制 React
  • 微应用兼容 single-spa 的微应用标准,支持 mount/unmount
  • 微应用和微模块概念合并为微应用

核心应用场景

  1. 大型应用的工程拆分,解决协作&效率问题
  2. 局部页面/模块的开放能力,交给二方团队开发,动态加载渲染

API 变化

  • 新增 regsiterMicroApps、start API,不耦合 React/Vue,在框架应用里使用,微应用注册通过路由匹配
  • AppRouter/AppRoute 保持不变,作用等价于 createMicroApp&start,框架应用如果是 React,可以选择使用
  • 新增 createMicroApp/unloadMicroApp API,用于独立渲染微应用,这种场景下微应用是一个独立的模块或页面,不应该包含路由(无法保证路由正确响应)
  • /stark-module 不再推荐使用,推荐切换为 loadMicroApp API
  • 微应用标准推荐 mount/unmountregisterAppEnter 可继续使用,自执行 render 的 bundle 会有 warning 提醒(之前已经有了)

新增 API 设计

regsiterMicroApps

框架应用中注册微应用

js
import { regsiterMicroApps } from '/stark';

regsiterMicroApps([
  {
    name: 'appname', // 微应用唯一标识(目前通过 path 进行标识)
    sandbox: true,  // 开启沙箱,可按规范定制自定义沙箱
    title: '页面标题',  // 微应用加载后页面标题
    hashType: true,  // 微应用 history 类型
    activePath: () => true,  // 根据当前路由变化自定义进行判断是否激活微应用
    container: 'icestarkNode',  // 微应用挂载节点
    url: ['//icestark.com/index.js', '//icestark.com/index.css'],  // 微应用 assets 资源,同 entry 二选一
    entry: '//icestark.com/index.html',  // 微应用 html 资源,同 url 二选一
    entryContent: '<div>ssss</div>',  // 微应用 html 页面中的内容,同 url 二选一
    render: () => {}, // 根据路由激活的自定义渲染逻辑,用于 iframe 和框架应用视图等内容的挂载
    cache: true,  // 缓存 assets 资源设置,
    props: {}, // 由框架应用传递给微应用的属性
  }
]);

微应用标准上兼容导出 bootstrap / mount / unmount 的 umd 规范

start

框架应用中启动整体应用

js
import { start } from '/stark';

start({
  onRouteChange: () => {},  // 中心化监听路由变更
  onAppEnter: () => {},  // 监听微应用挂载
  onAppLeave: () => {}, // 监听微应用卸载
  onLoadingApp: () => {}, // 监听应用加载过程
  onError: () => {},  // 应用加载出错
  onNotFound: () => {}, // 无法匹配微应用
  shouldAssetsRemove: () => true, // 判断资源是否卸载
});

能力上对齐 AppRouter,初始化阶段劫持路由以及一些事件的监听

mount/unmount

微应用除了目前 icestark 支持的调用 API 注册生命周期的方式外,可以通过构建出 UMD,UMD bundle 需要导出生命周期函数: - mount:微应用挂载 - unmount:微应用卸载

js
// 以 react 应用为例,微应用需要导出以下两种方法
export mount = (container, props) => {
  // container 为 微应用所挂载的节点
  // props 为自定义的透传的属性
  ReactDOM.render(<comp></comp>, container);
};

export const unmount = (container) => {
  // container 为 微应用所挂载的节点
  ReactDOM.unmountComponentAtNode(container);
};

createMicroApp

主动加载并渲染一个微应用,与路由无关。

js
createMicroApp({
  name: 'app',
  url: [
    '//ice.alicdn.com/icestark/child-seller-react/index.js',
  ],
  container: document.getElementById('icestark-container'),
});

通过 createMicroApp 可以将微应用的相关资源进行加载,并执行微应用导出的 mount 方法

实现思路

目前 icestark 中支持的能力进行精细化拆分,对应的能力统一封装后对外暴露 API 及在 AppRouterAppRoute 中调用

核心能力拆分:

  • 路由劫持方法
  • 路由匹配计算
  • 微应用资源加载,支持 url / entry 模式
  • 微应用生命周期获取,兼容 registerAppEnter / regsiterAppLeave 和 bootstrap / mount / unmount
  • 微应用更新机制

使用方式

基于路由控制的微前端应用

js
// 框架应用中通过 API 方式注册微应用
import { registerMicroApps, start } from '/stark';

registerMicroApps([
  {
    name: 'app1',
    activePath: '/test1',
    container: document.getElementById('icestark-container'),
    url: ['http://localhost:3444/js/index.js'],
  },
  {
    name: 'app2',
    activePath: ['/test2'],
    container: document.getElementById('icestark-container'),
    url: ['//ice.alicdn.com/icestark/child-seller-react/index.js'],
  },
  {
    name: 'app3',
    container: document.getElementById('icestark-container'),
    activePath: (url) => {
      return url.indexOf('test3') > -1;
    },
    url: ['//ice.alicdn.com/icestark/child-seller-react/index.js'],
  }
]);

// 微应用注册完成注册后,初始化路由劫持逻辑,并根据路由规则自动处理微应用激活/卸载
start({
  onAppEnter: () => {}
});

手动加载并渲染微应用

js
import { createMicroApp, unloadMicroApp } from '/stark';

// 加载未注册微应用
createMicroApp({ name: 'app2', url: [...], container: document.getElementById('icestark-container')});

// 基于 react 体系下模块加载
const MicroApp = () => {
  const appContainer = useRef(null);
  useEffect(() => {
    createMicroApp({ name: 'app2', url: [], container: appContainer.current });
    return () => {
      unloadMicroApp('app2');
    }
  }, []);
  return <div ref="{appContainer}"></div>
};

细节补充

微应用入口配置

支持下面几种形式:

  • entry:对应 html url 地址
  • url:对应 css/js 的 url 地址
  • entryContent:对应 HTML 内容
  • render:渲染自定义组件, 与 1.0 有变化,需要自己调用类似 ReactDom.render 的 API
  • component:不再支持,收敛到 render

路由匹配的配置

  • path 改为 activePath,对于 AppRouter 兼容原先的 path
  • activePath 在原先 string/array 的基础上,新增函数支持更灵活的判断

该提问来源于开源项目:ice-lab/icestark

  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 复制链接分享

7条回答 默认 最新

  • weixin_39854778 weixin_39854778 2020-11-23 02:59

    这个功能,什么时候能发布?

    点赞 评论 复制链接分享
  • weixin_39943868 weixin_39943868 2020-11-23 02:59

    container 需要支持 string | HtmlElement 两种使用方式

    点赞 评论 复制链接分享
  • weixin_39588084 weixin_39588084 2020-11-23 02:59
    • createMicroApps 改成 registerMicroApps 语义上更合理
    • 主动加载微应用的场景,是否需要提前中心化注册?如果需要的话,API 是否应该跟 createMicroApp 区分开?
    • url 的类型要再确认下
    • mount/unmount 以及函数参数需要补充
    点赞 评论 复制链接分享
  • weixin_39618169 weixin_39618169 2020-11-23 02:59
    • createMicroApps 改成 registerMicroApps 语义上更合理
    • 主动加载微应用的场景,是否需要提前中心化注册?如果需要的话,API 是否应该跟 createMicroApp 区分开?
    • url 的类型要再确认下
    • mount/unmount 以及函数参数需要补充
    • createMicroApps 实际上做的就是 register 的事情,的确 registerMicroApps 更合理
    • 是否中心化注册跟开发习惯关联比较大,类似 registerMicroApp 的方式内部还是会实现,默认推荐使用配置的方式直接加载
    • url 类型支持 string | string[],通过资源后缀对资源类型进行区分,约定最后一项 js 资源为默认主 entry bundle
    • mount/unmount 已补充
    点赞 评论 复制链接分享
  • weixin_39603217 weixin_39603217 2020-11-23 02:59

    希望在主应用和子应用之间的数据流通上能做的方便一点,拿model 的 state 和 dispatcher 举例,目前所使用的 /stark-data 的效果是:

    1 state:主应用 set state 到 stark-data,子应用监听到消息后再把数据初始化到自身; 2 dispatcher:主应用 set dispatcher 到 stark-data ,子应用在调用主应用中的 dispatcher 时要先去 stark-data 中获取;

    在使用了 model 的时候,这个过程就很麻烦,stark-data 相当于一个第三方中转,但是不做主动的数据分发(需要开发者自己做把stark-data 中的数据同步到 model,调用 dispatcher 从 stark-data 中取)。

    所以个人想法是希望能出更加便捷的工具,实现主应用子应用的数据互通,不需要第三方中转,或者这个中转能够主动分发数据到 model。

    点赞 评论 复制链接分享
  • weixin_39618169 weixin_39618169 2020-11-23 02:59

    希望在主应用和子应用之间的数据流通上能做的方便一点

    首先主子应用设计上尽量不要有太多耦合,2.0 方案里面在挂载子应用的时候可以传递主应用自定义的 props,一定程度上可以降低共享属性的成本,后续也会考虑 stark-data 的优化

    点赞 评论 复制链接分享
  • weixin_39615219 weixin_39615219 2020-11-23 02:59

    1.从当前子应用跳转到另一个子应用返回后,希望能复原当前子应用的状态,例如:滚动条位置,查询条件,当前页数等信息。类似Vue的keep-alive 2.子应用路由能支持router.pop()返回前一个子应用

    点赞 评论 复制链接分享

相关推荐