epm-extend-core
该项目为 EPM 扩展机制核心库
执行 npm install @epmkit/epm-extend-core
来引入该库。
开发
npm start
执行 npm start
进行开发
public 目录下的文件并不是用来发布的,而是调试用的例子插件。
npm run build
执行 npm run build
进行编译
使用
核心库引入
在宿主环境中执行 npm install @epmkit/epm-extend-core
来引入该库。
与该库配套使用的 @epmkit/cra-template-epm-plugin
用来创建插件仓库。
在节点中使用 Extend 机制
引入方法如下所示:
import React, { useEffect, useState } from 'react';
import Extend from '@epmkit/epm-extend-core';
const ExtendContext = React.createContext('Extend');
function App() {
const [ExtendInstance, setExtendInstance] = useState(new Extend());
useEffect(() => {
async function initExtend() {
cosnt config = await fetchPluginList(nodeCode);
ExtendInstance.init(config);
setExtendInstance(ExtendInstance);
}
initExtend();
return () => {
ExtendInstance.dispose();
};
}, []);
return (
<ExtendContext.Provider value={ExtendInstance.Slot}>
<ChildElement />
</ExtendContext.Provider>
);
}
function ChildElement() {
const Slot = React.useContext(ExtendContext);
return <Slot name='slot-name' sandbox={false} fn={{
fnAAA: () => {/* 事件回调 */},
fnBBB: () => {/* 事件回调 */}
}} data={{
dataAAA: '', // 传递数据
dataBBB: {}
}} />;
}
-
在节点的最外层执行 React.createContext('Extend')
创建扩展机制执行上下文
-
在节点中执行 new Extend(options)
创建 扩展机制实例 ExtendInstance
扩展机制支持对一些配置进行自定义设置,具体可设置属性如下:
字段 | 含义 | 类型 | 默认值 |
---|
defaultStyleUrl | 默认样式CSS地址 | string | //design.yonyoucloud.com/static/tinper-next/release/tinper-next.css |
windowScope | 插件绑定到window对象上的属性 | string | epmPlugin |
sandbox | 是否开启js沙箱 | boolean | true |
-
在适当的时机执行实例的 init
方法,并传入插件插槽配置。init
时传入的 config
变量为当前节点的插件插槽配置项,需要符合特定的数据结构,以下为例子:
config = {
pluginList: [
{
name: 'aSmallBtn',
scriptEntry: 'http://localhost:3030/plugin-aSmallBtn.e76d9341.js',
styleEntry: 'http://localhost:3030/plugin-aSmallBtn.ababa1e9.css',
version: '1.3.0',
sandbox: false,
},
{
name: 'aSelectExample',
scriptEntry: 'http://localhost:3030/plugin-aSelectExample.e86c0e5e.js',
styleEntry: 'http://localhost:3030/plugin-aSelectExample.5df6a4d9.css',
chunks: ['http://localhost:3030/js/plugin-chunk.155.cb4c80ac.js'],
version: '1.4.1',
},
],
slotList: [
{
name: 'slot-a',
plugins: ['aSelectExample', 'aSmallBtn'],
},
{
name: 'slot-b',
plugins: ['aSelectExample'],
},
{
name: 'slot-c',
plugins: [{ name: 'aSelectExample', version: '1.4.1' }],
},
],
};
各字段含义如下
字段 | 含义 | 类型 | 例子 | 是否必需 |
---|
pluginList | 当前节点的插件列表 | Array<Plugin> | - | √ |
Plugin.name | 插件名 | string | aSmallBtn | √ |
Plugin.scriptEntry | 插件脚本文件入口地址 | string | http://localhost:3030/plugin-aSmallBtn.e76d9341.js | √ |
Plugin.styleEntry | 插件样式文件入口地址 | string | http://localhost:3030/plugin-aSmallBtn.ababa1e9.css | - |
Plugin.chunks | 插件的分包 | Array<URL> | ['http://localhost:3030/js/plugin-chunk.155.cb4c80ac.js'] | - |
Plugin.version | 插件的版本 | string | 1.3.0 | - |
Plugin.sandbox | 是否开启沙箱,默认开启,可设置为 false 对单个插件关闭 | boolean | false | - |
slotList | 当前节点的插槽配置 | Array<Slot> | - | √ |
Slot.name | 插槽名 | string | slot-a | √ |
Slot.plugins | 当前插槽的插件列表 | Array<string|Plugin> | - | √ |
-
将扩展机制实例的插槽 ExtendInstance.Slot
作为上下文的值传递给子组件
-
在子组件适当的位置使用 <Slot name='slot-name' />
注入插槽
插件开发
EPM 扩展机制核心库是和插件配置来使用的,插槽的开发者使用核心库来配置插槽和传递的数据方法,插件开发者需要开发插件来注入应用。
插件开发者执行 npx create-react-app ${plugin-repo-name} --template @epmkit/cra-template-epm-plugin
来创建插件仓库,其中 ${plugin-repo-name}
为插件仓库的名称。
插件的开发同普通 React 组件开发方式相同,只不过组件的 props 是通过插槽传递过来的数据。
一个插件例子如下:
export default function SamllBtn({ fn, data, emit, on }) {
const { btnName, isBtnShow } = data;
const { hideBtn, showBtn } = fn;
useEffect(() => {
on('anotherPlugin:message', payload => {
console.log('receiveMessage', payload);
});
}, []);
const handleClick = useCallback(() => {
if (isBtnShow) {
hideBtn();
return;
}
showBtn();
emit('smallBtnClick', !isBtnShow);
}, [hideBtn, isBtnShow, showBtn]);
return (
<Button
className='plugin-btn'
style={{ width: 400 }}
onClick={handleClick}
type='primary'>{`${btnName}按钮`}</Button>
);
}
插件的 props 含义如下:
字段名 | 含义 | 例子 |
---|
fn | 由插槽定义的方法,通过执行方法改变页面状态 | - |
data | 由插槽传递的数据,获取当前插槽传递的实时数据 | - |
emit | 插件间通信方法,发送事件与数据 | emit('event', data) |
on | 插件间通信方法,监听其他插件发送的事件并对载荷做出处理 需要注意的是,监听时需要带上监听的插件名,插件名和事件之间以冒号 : 连接 | on('pluginName:event', (payload) =>{}) |