框架简介
icestark
是一个面向大型系统的微前端解决方案,适用于以下业务场景:
- 后台比较分散,体验差别大,因为要频繁跳转导致操作效率低,希望能统一收口的一个系统内;
- 单页面应用非常庞大,多人协作成本高,开发/构建时间长,依赖升级回归成本高;
- 系统有二方/三方接入的需求;
icestark 在保证一个系统的操作体验基础上,实现各个子应用的独立开发和发版,框架应用通过 icestark 管理子应用的注册和渲染,将整个系统彻底解耦。
官方文档:https://ice.work/docs/icestark/about
知乎:面向大型工作台的微前端解决方案 icestark
GitHub:https://github.com/ice-lab/icestark
原理
劫持history
相关的跳转事件,捕获到页面跳转事件=》根据url查找相关子应用信息=》与之前的子应用信息相同,则什么都不做;如果是不同的子应用,则将前一个子应用的 bundle 卸载,同时加载新的子应用 bundle 资源。
快速上手
安装 CLI 工具
$ npm i -g iceworks
初始化框架应用
$ mkdir icestark-layout && cd icestark-layout
$ iceworks init project @icedesign/stark-layout-scaffold
# 安装依赖
$ npm install
# 启动服务
$ npm run start
开发子应用
$ mkdir icestark-child-app-test && cd icestark-child-app-test
# 基于 React 的子应用
$ iceworks init project @icedesign/stark-child-scaffold
# 基于 Vue 的子应用
$ iceworks init project @vue-materials/icestark-child-app
相比于传统的单页面应用,icestark 的子应用有三个需要定制的地方:
- 需要主动注册&触发应用的卸载事件
- 应用渲染的节点需要通过
getMountNode() API
来获取
// src/index.jsx
import ReactDOM from 'react-dom';
import { getMountNode, registerAppLeave } from '@ice/stark-app';
import router from './router';
registerAppLeave(() => {
ReactDOM.unmountComponentAtNode(mountNode);
});
ReactDOM.render(router(), getMountNode(document.getElementById('mountNode')));
- 路由需要定义在约定的基准路由(在框架中为子应用分配的)下面:
// src/router.jsx
import { BrowserRouter as Router, Switch } from 'react-router-dom';
import { getBasename } from '@ice/stark-app';
export default () => {
return (
<Router basename={getBasename()}>
<Switch>
// ...
</Switch>
</Router>
);
};
- 如有需要,可以使用
@ice/stark-data
实现应用间通信。具体实现参考:应用间通信
注册子应用
假设已有webpack构建好的文件index.js
和index.css
,在App.jsx
目录下注册子应用:
// src/App.jsx
const apps = [
...
// 注册子应用
{
// 为子应用分配的基准路由,可以是数组
path: "/test",
title: "测试子项目",
// 子应用的 bundle 地址,用来渲染子应用
url: ["//localhost:4445/js/index.js", "//localhost:4445/css/index.css"]
}
];
如有需要,添加菜单
// src/config/menu.js`
// 菜单配置
// headerMenuConfig:头部导航配置
// asideMenuConfig:侧边导航配置
...
const asideMenuConfig = [
...
{
name: "测试子页面",
icon: "account",
children: [
{
path: "/test",
name: "测试子页面"
},
{
path: "/test/list",
name: "小二列表"
}
]
}
];
export { headerMenuConfig, asideMenuConfig };
热更新后即可看到新添加的子应用。
其他
1. 子应用容器定制/应用级别权限校验
通过二次封装AppRoute
组件统一处理权限问题。子应用容器定制/应用级别权限校验
2. 应用间通信
如有需要,可以使用@ice/stark-data
实现应用间通信,使用方式类似localstorage。具体实现参考:应用间通信
对于框架应用和子应用,运行时都共享了当前页面的 location、Cookie、LocalStorage、window 等全局信息,因此应用间的通信,可以通过这些方案很简单的实现。
3. 子应用跳转
内部跳转=》route提供的Link
组件
跳转到其他子应用=》appHistory
API
import { appHistory } from '@ice/stark-app';
<Button type="primary" onClick={() => {
appHistory.push('/seller/settings');
}}>跳转到其他子应用</Button>
- qiankun框架 :https://qiankun.umijs.org/zh/
- 其他方案: 实施前端微服务化的六七种方式
- other 前端微服务化解决方案