# 扩展点的设计原则
重要提醒
- 扩展点的设计很重要,在插件化开发过程中需要严格按照规范进行设计。
- 扩展点一旦定义,项目中禁止删除或修改,仅可新增功能点。
- ⭐️⭐️⭐️⭐️⭐️ 扩展点的层级只能有一层,不可以嵌套的形式进行使用;一旦存在嵌套,其维护和变更成本将呈几何形式上升。
# 插件的意义是旨在解决后续项目升级问题,所以须保证插件的独立性。本篇主要介绍在实际插件化项目中插件独立性的checklist
# 扩展点的颗粒度
简介:扩展点的颗粒度的大小依据于业务的定制化差异大小。在确定扩展点的颗粒度大小时,推荐以下两种方式:
# 1. 布局型扩展点【根据页面布局挖取扩展点】
- 优势:
- 上手简单,覆盖面广:单一页面仅需维护极少的扩展点即可覆盖所有的定制化需求。
- 高内聚:扩展点通常将相关的功能、状态和样式集中在一起管理;使代码更加内聚,易于理解和维护。
- 变更成本低:可在当前扩展点内定制各种大小需求,无需担心扩展点的变更问题。
- 劣势:
- 开发/维护成本高:大型扩展点可能会存在与主应用相同的大量的重复代码。例如:若顶部扩展点某个按钮的功能是定制化功能时,整个顶部扩展点都需要定制一份;当主应用的顶部扩展点(除按钮的功能)功能进行优化升级时,定制的扩展点也需要进行优化升级。
- 依赖关系深入:大型扩展点可能与其他扩展点或宿主有深层次的依赖关系(如:数据、指令集等),引入时的复杂度增加。
- 体积过大:大型扩展点通常包含大量的代码和资源,会导致前端包的体积过大,影响页面的加载性能。
- 适用场景:适用于定制化功能比较集中、比较复杂,定制化区域比较大的场景
# 2. 功能型扩展点(根据定制功能点挖取扩展点 例如:签署页)
- 优势:
- 开发/维护成本低:小型扩展点通常只关心某一特定功能,代码简洁,易于理解和维护。
- 依赖关系清晰:小型扩展点通常不涉及过多的外部依赖,减少模块之间的复杂关系,便于定制和维护。
- 轻量化:小型扩展点的体积较小,减少网络传输和页面加载时间,提升用户体验。
- 劣势:
- 组合复杂性增加:当宿主需要组合使用多个扩展点时,可能需要编写更多的代码和逻辑来实现复合功能。
- 变更成本大:当扩展点无法满足定制化需求,需要进行变更时(即扩展点小变大),会增加更多的开发、测试成本。
- 适用场景:定制化功能比较分散、比较简单;定制化区域比较小的场景
# 扩展点的变更流程
# 数据store
- store设计需要语义化,参数字段需要平铺细化,后期影响范围可追溯(包括给插件提供路由中的传递参数);
- 不能直接包一个无语义化的对象。
- 插件中禁止直接通过storage(local/session/cookie)的方式获取或设置主应用中缓存的数据,必须通过指令集的方式由主应用提供。插件中的临时存储除外
# 指令集
提示
指令集命名需要语义化,类似open-api,一旦暴露需要固化
# 1. 指令集按通用性分类
工具类(util)
流程类(process)
event类(event)
上行数据方法(uplink)
# 2. 命名规范: 扩展点名称-指令类型-业务特性
例:login-page-epu-event-login
# 3. 扩展点与指令集设计原则
一对一(即 一个扩展点对应一个指令集),例如 扩展点home-page-body-epu
对应的指令集如下:
/**
* 指令集命名规范:扩展点名称-指令类型-业务特性(例如:登录页扩展点-流程类-登录)
*/
const global: any = window
/**
* 工具类指令集
*/
const utilsApi = {}
/**
* 流程类指令集
*/
const processApi = {}
/**
* event指令集
*/
const eventApi = {
toSealList: () => {
// 点击前往印章列表
global.esignbridge.$eventEmitter.emit('home-page-body-epu-event-sealClick')
},
}
/**
* 上行数据
*/
const uplinkApi = {}
export default { ...eventApi, ...utilsApi, ...processApi, ...uplinkApi }
# 4. npm的独立性,插件&主应用独自依赖,可升级
i. 基线指令通过import引入指令集监听处理
ii. 插件通过window.esignbridge.xxx调用指令集
# 5. 路由触发
插件中不能直接调用主应用的路由跳转,需要通过指令集通知主应用,由主应用进行跳转(因为主应用的router name或path是可变的,插件不能直接触及,即防止后续升级插件不可用)
# 依赖独立性
# 多语言
# 组件
# 工具类
# 接口API
i. 调用基线能力,使用指令集
ii. 调用插件能力,使用基线http封装对象
# 扩展点属性
# 1. 空逻辑
基线扩展点支持空逻辑,即基线实现逻辑扩展点而不实现插件,也不阻塞业务流程
# 2. 宽度、高度等
UI类扩展点需要有对应的宽度高度等样式属性
# 插件包体积
影响性能
# 1. 图片资源--base64
# 2. 剔除包含多余的三方依赖
# window挂载对象覆盖(待开发)
# js沙箱隔离
# css样式覆盖
问题:主应用中引入elementUI样式后并重写覆盖某些样式,插件中也单独引入了elementUI及其样式,因css权重问题导致插件中引入的样式覆盖主应用中的样式。
解决方案:通过修改编译后的插件所使用的基础组件的前缀,解决样式覆盖问题。@esign/css-prefix-webpack-plugin
警告事项
插件中基础组件的局部注册,建议以 双驼峰
命名发进行注册。
例如:
import { Button } from 'element-ui'
...... /* 省略代码 */
components: {
ElButton: Button
}
...... /* 省略代码 */