核心问题
- 用户端必须是「一个系统」的心智,从域名到体验
- 能够根据功能拆分成多个子应用,每个子应用独立开发独立部署
- 子应用尽量保证跟传统单页面应用一样的开发体验,不要让开发者有太多学习成本
- 所有子应用可被统一管理起来,不能无限制的泛滥
现有集成方案
- iframe
成本低,体验差 - 直接加载js
项目侵入小,可能存在性能问题- 普通项目,直接调用
ReactDOM.render(\<App />, node )(可能存在内存问题) - 注册钩子,icestark
- 普通项目,直接调用
- 暴露生命钩子single-spa
变更打包配置https://github.com/umijs/qiankun/blob/master/examples/react16/.rescriptsrc.js
// 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:为什么要支持钩子
- 不同技术栈的系统支持
- 事件、数据隔离
- 性能优化
系统组成部分
子应用
分两种类型
- 普通项目
ReactDOM.render(<App />, node);这种形式的 iif 支持直接加载 - 暴露钩子的项目 注册生命周期钩子
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'));
}
具体实现思路:
- 注册全局变量,当前env=微前端,当前loading的子应用名
- 加载js,调用registerMount
- 子应用名称和cb关联
脚手架
项目初始化
tnpm @alife/linkdesign-cli init
> App
Component
MicroApp(微应用) ✅
package.json
{
"name": "应用名,必须唯一,在注册时校验"
"description": "描述"
"version": "版本"
}
实现:
- 结合def,cdn发布后同时调用对应环境接口,注册新版本
- 支持模拟微应用场景下调试如: 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框架
涉及的功能
- cdn加载
- iframe加载
- html解析加载
- 生命钩子加载
- 数据、样式隔离
- 主应用路由和微应用路由不冲突
https://yuque.antfin-inc.com/iothangye/iif/ys7lxc
@linkdesign/microapp
微应用框架之外的能力集,环境区分、应用注册、调试等
- 子应用注册、更新
- 子应用数据获取
- 主应用生命周期注册
- 本地环境夸应用调用
- 事件机制
微应用管理平台
管理各个微应用基本信息和版本,后续展示各个微应用使用情况
字段
name: 名称
description: 描述
version: 版本
css:css资源
js:js资源
external: 依赖资源
author:创建人
git地址
主应用端接口
- getDetail?name 根据名称获取应用最新版本信息
- getDetail?version 根据名称和版本获取应用信息
- getDetailBatch 批量获取信息
脚手架端接口(根据资源cdn地址触发不同环境接口)
- checkIsExistByName 判定当前应用名称是否已存在
- createOrUpdate 创建或者更新应用信息
平台端接口
- getList 获取应用列表(列表)
- getVersionById 获取应用当前版本列表(当前生效版本,最新版本)
- setProdVersion 设置应用生效版本(用于二次确认上线、回滚)
Portal层接入
可能性:
- 子应用版本管理?(子应用发布新版本情况下,主应用不知,是否要锁版本)
- 通过view直接搭建出项目
- WebComponent
- 路由关联子应用
与能力中心对接
老应用接入
- 入口文件添加isMicrpApp判断代码
- 注册到微应用平台
其他问题
子应用跳转其他子应用
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
子应用切换时数据隔离
其他涉及功能
- 监控接入,各个微应用,各个版本被使用情况分析
- 路由动态下发
- 项目接入(通用Layout,在onePortal直接配置)
- 子应用参数配置
- 公共鉴权功能
