大鹿
Jiann
Do not go gentle into that good night. 🏕️

微应用集成方案

核心问题

  • 用户端必须是「一个系统」的心智,从域名到体验
  • 能够根据功能拆分成多个子应用,每个子应用独立开发独立部署
  • 子应用尽量保证跟传统单页面应用一样的开发体验,不要让开发者有太多学习成本
  • 所有子应用可被统一管理起来,不能无限制的泛滥

现有集成方案

// webpack.config.js
module.exports = {
  entry: './add.js',
  output: {
    filename: 'add.js',
    libraryTarget: 'umd',
    library: 'add'
  }
}

<script src="./dist/add.js"></script>
  <script>
    console.log(window.add(1, 2));
  </script>
</script>

Tip:为什么要支持钩子

  1. 不同技术栈的系统支持
  2. 事件、数据隔离
  3. 性能优化

系统组成部分

子应用

分两种类型

  1. 普通项目 ReactDOM.render(<App />, node);这种形式的 iif 支持直接加载
  2. 暴露钩子的项目 注册生命周期钩子
import ReactDOM from 'react-dom';
import { isMicroApp, registerMount, registerUnmount } from '@linkdesign/microapp';
import App from './App';

if (isMicroApp()) {
  registerMount(props => {
    ReactDOM.render(router(), props.container);
  });
  registerUnmount(props => {
    ReactDOM.unmountComponentAtNode(props.container);
  });
} else {
  ReactDOM.render(<App />, document.getElementById('ice-container'));
}

具体实现思路:

  1. 注册全局变量,当前env=微前端,当前loading的子应用名
  2. 加载js,调用registerMount
  3. 子应用名称和cb关联

脚手架

项目初始化

tnpm @alife/linkdesign-cli init
> App
    Component
    MicroApp(微应用) ✅

package.json

{
    "name": "应用名,必须唯一,在注册时校验"
    "description": "描述"
    "version": "版本"
}

实现:

  1. 结合def,cdn发布后同时调用对应环境接口,注册新版本
  2. 支持模拟微应用场景下调试如: npm run start --type=microapp

主应用

const config = [
 {
   path: '/a',
   name:"myapp1" // 子应用名称,对应注册时的名称。未定义js和css的情况下,拉取微应用配置信息
 },
  {
   path: '/b',
   name:"myapp2" // 
   version: "1.0.0" // 可配置版本,非必填
 },
]
//配置和启动
IIF.init(config).start();

IIF框架

涉及的功能

  1. cdn加载
  2. iframe加载
  3. html解析加载
  4. 生命钩子加载
  5. 数据、样式隔离
  6. 主应用路由和微应用路由不冲突

https://yuque.antfin-inc.com/iothangye/iif/ys7lxc

@linkdesign/microapp

微应用框架之外的能力集,环境区分、应用注册、调试等

  1. 子应用注册、更新
  2. 子应用数据获取
  3. 主应用生命周期注册
  4. 本地环境夸应用调用
  5. 事件机制

微应用管理平台

管理各个微应用基本信息和版本,后续展示各个微应用使用情况

字段

name: 名称
description: 描述
version: 版本
css:css资源
js:js资源
external: 依赖资源
author:创建人
git地址

主应用端接口

  • getDetail?name 根据名称获取应用最新版本信息
  • getDetail?version 根据名称和版本获取应用信息
  • getDetailBatch 批量获取信息

脚手架端接口(根据资源cdn地址触发不同环境接口)

  • checkIsExistByName 判定当前应用名称是否已存在
  • createOrUpdate 创建或者更新应用信息

平台端接口

  • getList 获取应用列表(列表)
  • getVersionById 获取应用当前版本列表(当前生效版本,最新版本)
  • setProdVersion 设置应用生效版本(用于二次确认上线、回滚)

Portal层接入

可能性:

  • 子应用版本管理?(子应用发布新版本情况下,主应用不知,是否要锁版本)
  • 通过view直接搭建出项目
  • WebComponent
  • 路由关联子应用

与能力中心对接

老应用接入

  1. 入口文件添加isMicrpApp判断代码
  2. 注册到微应用平台

其他问题

子应用跳转其他子应用

import { Link, history } from '@linkdesign/microapp';

1. 组件触发
<Link name="微应用名" path="/getail?id='100'">跳转</Link>
2. 方法调用
history.push({
  name: '微应用名',
  path: "/getail?id='100'"
})

本地调试:异步加载对应已发布的微应用。主应用内最终跳转地址为/微应用名对应的一级路由/path

子应用公共库处理

子应用自己维护依赖库,如果配置external,则由脚手架作为依赖项注册到平台中

子应用内接口

子应用内接口地址都应连带域名,否则被集成到其他项目时无法调用

子应用版本上线脱离OnePortal

子应用切换时数据隔离

其他涉及功能

  1. 监控接入,各个微应用,各个版本被使用情况分析
  2. 路由动态下发
  3. 项目接入(通用Layout,在onePortal直接配置)
  4. 子应用参数配置
  5. 公共鉴权功能