微应用集成
Pangea目前支持iframe及微前端两种方式的第三方页面集成显示,本节重点介绍微前端集成方式。
微应用集成要求
Pangea采用qiankun
微应用集成方案,微应用需要集成到Pangea需要满足以下几个条件:
1、打包方式
为了让Pangea能正确识别微应用暴露出来的一些信息,微应用应打包为umd模式,以webpack打包工具为例需要增加如下配置:
javascript
const packageName = require('./package.json').name;
module.exports = {
output: {
library: `${packageName}`,
libraryTarget: 'umd',
jsonpFunction: `webpackJsonp_${packageName}`,
},
};
2、导出生命周期钩子
微应用需要在自己的入口 js (通常就是你配置的 webpack 的 entry js) 导出 bootstrap、mount、unmount 三个生命周期钩子,以供主应用在适当的时机调用。下面以vue工程为例:
javascript
window.subVm = null;
/**
* bootstrap 只会在微应用初始化的时候调用一次,下次微应用重新进入时会直接调用 mount 钩子,不会再重复触发 bootstrap。
* 通常我们可以在这里做一些全局变量的初始化,比如不会在 unmount 阶段被销毁的应用级别的缓存等。
*/
export async function bootstrap() {
console.log('react app bootstraped');
}
/**
* 应用每次进入都会调用 mount 方法,通常我们在这里触发应用的渲染方法
* @param Object props
* {
* token: "******"
* }
*/
export async function mount(props) {
// props中包含token等从Pangea传递来的参数,供微应用使用。
...to do something with props
// 动态监听Pangea传递参数
props.onGlobalStateChange(state => { });
if (!window.subVm) {
window.subVm = new Vue({
router,
store,
i18n,
render: h => h(App)
}).$mount(props.container.querySelector("#root"));
}}
/**
* 应用每次 切出/卸载 会调用的方法,通常在这里我们会卸载微应用的应用实例
*/
export async function unmount(props) {
window.subVm.$destroy();
window.subVm = null;
}
/**
* 可选生命周期钩子,仅使用 loadMicroApp 方式加载微应用时生效
*/
export async function update(props) {
console.log('update props', props);
}
3、支持跨域访问
微应用部署时需支持跨域访问。若未设置在集成时,浏览器控制台会报如下错误:
未设置允许跨域浏览器提示错误
Access to fetch at '子应用域名' from origin '主应用域名' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
下面以nginx配置为例,需进行以下配置:
bash
location / {
try_files $uri $uri/ /index.html;
add_header Access-Control-Allow-Origin *;
add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS';
add_header Access-Control-Allow-Headers 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization';
}
注意当被集成到的主应用域名可确认时,可将add_header Access-Control-Allow-Origin
属性值由*
替换为主应用的域名。
4、http、https协议需统一
主应用及子应用的http,https协议需统一。即若主应用使用https协议,子应用也需要使用https协议才可正常集成。若未设置一致,浏览器控制台会报如下错误:
http、https协议未统一浏览器提示错误
The page at '主应用域名' was loaded over HTTPS, but requested an insecure resource '微应用域名'. This request has been blocked; the content must be served over HTTPS.
5、动态设置
微应用能够通过window.__POWERED_BY_QIANKUN__
(boolean)变量得知当前访问方式为独立访问还是通过Pangea集成访问。当集成到Pangea时,在微应用导出的mount(props)
钩子函数的props参数中,可获取到token
等从主应用传递来的参数。
1、 隐藏布局 当微应用通过Pangea集成访问时,页面应用隐藏布局类(头部导航、菜单等)组件的展示,只呈现内容区域。
2、取消登录逻辑 当微应用通过Pangea集成访问时,微应用应取消登录逻辑控制,取Pangea传递到微应用的token控制权限。
6、路由注册
Pangea路由路径中的第一段为应用编码(appCode),而业务微应用无应用的概念,所以微应用中的路由注册需要调整,需要在第一段添加一个动态参数,下面代码以vue工程为例,react工程同理。
javascript
const router = new VueRouter({
routes: [
// 首段为动态路径参数,以冒号开头
{ path: '/:appCode/path1/path2', component: Demo }
]
})
上面的代码中/path1/path2
为原工程路径,/:appCode/path1/path2
为调整后的路径,这样就可以保证在不同的应用挂载该页面时,即:appCode
为任意值时都可以访问到Demo组件。 注意:
- 路由调整后,工程中涉及到路由跳转的代码也需相应调整。跳转路由的第一段可到浏览器路径中得到。
/${window.location.pathname.split("/")[1]}/path1/path2
- 微应用路由跳转使用history.pushState()
应用通讯
主应用与微应用前可进行参数传递及参数变化监听。
参数传递
在微应用集成要求中提到,需要将系统初始化函数放到mount(props)
生命周期函数中,在mount(props)
函数中会接收到从主应用传递来的props
参数,props
参数类型为对象,里面包含了以下对象属性(如需其它参数,请联系Pangea项目组):
参数名 | 参数类型 | 参数描述 |
---|---|---|
pangeaToken | String | pangea系统登录验证token |
参数变化监听
主应用存在一些全局动态参数,这些参数可控制微应用的某些状态进行动态变化,微应用需要监听这些参数的变化以实现微应用某些状态的变化。 微应用通过以下mount函数中props参数的onGlobalStateChange方法监听主应用参数变化,其中state参数包含了变化的参数。
javascript
export async function mount(props) {
props.onGlobalStateChange(state => {
// 这里执行state变化后变化后的逻辑
})
}
state对象中有如下动态参数属性:
intl
intl为国际化相关的参数,为对象类型,存在两个属性: (1)language:语言类型编码,如:zh_CN 表示中文 (2)values:language对应的语言的国际化Key列表
Pangea集成微应用页面
1、维护微应用数据
在微应用管理菜单进行微应用数据的维护。
2、Pangea菜单
参考应用管理章节创建应用,在维护应用菜单时,选择微应用
菜单类型,路由
维护为和微应用集成页面路由一致,微应用
选择为该集成页面所在的微应用。
3、微应用按钮集成
参考应用管理章节创建应用,在维护应用菜单时,选择微应用
菜单类型,按钮配置
配置为需要的按钮权限对应的名称和编码
第二步:在角色中配置权限,找到对应的应用-菜单,需要展示的按钮权限勾选上。(这个时候已经会将按钮权限传递给微应用)
第三步:在微应用中配置代码,接收权限按钮列表
javascript
/**
*应用每次进入都会调用mount方法,通常我们在这里触发应用的渲染方法
*/
export async function mount(props){
props.onGlobalStateChange((state)=>{
console.log('子应用接收参数--buttonList',state.buttonList)
}, true)
}
微应用脚手架
Pangea提供了vue版本和react版本的微应用脚手架供项目组参考使用。
vue脚手架 (vue + antd) git地址:http://gitlab.hisense.com/Pangea/Pange-Cloud/frontend/vue-sub-web.git
react脚手架 (react + antd + dva + webpack) git地址:http://gitlab.hisense.com/Pangea/Pange-Cloud/frontend/pangea-dva.git