
深入解析 lowcode-engine 插件实例模型 PluginInstance属性、依赖与元数据机制【免费下载链接】lowcode-engineAn enterprise-class low-code technology stack with scale-out design / 一套面向扩展设计的企业级低代码技术体系项目地址: https://gitcode.com/GitHub_Trending/lo/lowcode-engine插件体系是 lowcode-engine 低代码引擎的核心扩展机制而PluginInstance插件实例则是描述一个已注册插件在运行时状态的标准模型。本文以 docs/docs/api/model/plugin-instance.md 中的模型定义为主线结合仓库内类型定义与 Shell 层实现系统讲解pluginName、dep、disabled、meta四个属性的语义、取值来源与典型使用场景并深入IPublicTypePluginMeta元数据背后的依赖声明、引擎版本兼容、事件前缀与命令作用域等机制。读完本文你将能在自己的插件开发与宿主集成中准确读写插件实例实现依赖编排、启停控制和元数据读取。一、什么是插件实例 PluginInstance在 lowcode-engine 的架构中插件Plugin通过plugins.register()注册到插件管理器注册后由插件管理器实例化出对应的运行时对象ILowCodePluginRuntime。PluginInstance 是面向外部使用者的只读/受限访问模型它把运行时内部细节收敛为四个稳定的公开属性屏蔽底层实现差异。对应的公开类型为IPublicModelPluginInstance定义于 packages/types/src/shell/model/plugin-instance.ts该模型自引擎v1.1.0起提供since v1.1.0Shell 层的具体实现类为PluginInstance位于 packages/shell/src/model/plugin-instance.ts它内部持有运行时对象ILowCodePluginRuntime并以pluginInstanceSymbol作为私有字段的隐藏键。// packages/types/src/shell/model/plugin-instance.ts节选 export interface IPublicModelPluginInstance { disabled: boolean; get pluginName(): string; get dep(): string[]; get meta(): IPublicTypePluginMeta; }从上述接口可以看到pluginName、dep、meta是只读 getter而disabled是唯一可读写的属性——这正是实例状态语义的体现插件身份与依赖不可变但启用/禁用状态可在运行期调整。二、如何获取插件实例PluginInstance 通常不是由开发者直接new出来的而是通过插件管理 API 从插件管理器中取得。在 Shell 层plugins.get()与plugins.getAll()会把底层运行时对象包装为公开的插件实例模型// packages/shell/src/api/plugins.ts节选 get(pluginName: string): IPublicModelPluginInstance | null { const instance this[pluginsSymbol].get(pluginName); if (instance) { return new ShellPluginInstance(instance); } return null; } getAll(): IPublicModelPluginInstance[] { return this[pluginsSymbol].getAll()?.map((d) new ShellPluginInstance(d)); }典型用法// 通过插件上下文或编辑器拿到 plugins API const plugins editor.get(plugins); // 按名称获取单个插件实例 const outlinePane plugins.get(PluginOutlinePane); if (outlinePane) { console.log(outlinePane.pluginName); // PluginOutlinePane console.log(outlinePane.disabled); // false } // 获取全部插件实例 const all plugins.getAll(); all.forEach((p) console.log(p.pluginName, p.dep, p.meta));注意get()在插件不存在时返回null使用前应做空值判断。三、核心属性详解3.1 pluginName插件名字类型stringpluginName是插件的唯一标识名注册插件时定义即IPublicTypePlugin上的pluginName字段运行期不可修改。在 Shell 实现中它直接透传运行时对象的name// packages/shell/src/model/plugin-instance.ts get pluginName(): string { return this[pluginInstanceSymbol].name; }它在整个插件体系中承担多重职责作为plugins.get(pluginName)、plugins.has(pluginName)等 API 的查找键作为插件上下文的事件命名空间来源之一见下文meta.eventPrefix的推荐用法作为插件间依赖声明dep的引用目标。3.2 dep插件依赖类型string[]dep表示当前插件所依赖的其他插件名称列表。lowcode-engine 插件管理器在初始化时会依据各插件的dep进行依赖排序拓扑初始化确保被依赖的插件先完成初始化再初始化依赖方从而避免使用尚未就绪的插件的问题。// packages/shell/src/model/plugin-instance.ts get dep(): string[] { return this[pluginInstanceSymbol].dep; }声明依赖的两种途径在插件meta.dependencies中声明推荐静态元数据在注册时通过dep传入依赖列表运行时声明。从源码结构看dep与meta.dependencies存在对应关系二者共同构成插件管理器的依赖解析输入。例如某个面板插件依赖大纲树插件时const MyPlugin (ctx) { // 依赖的插件已保证先初始化可安全使用 const outline ctx.plugins.get(PluginOutlinePane); return { init() { /* ... */ } }; }; MyPlugin.pluginName MyPlugin; MyPlugin.meta { dependencies: [PluginOutlinePane], };3.3 disabled插件是否禁用类型booleandisabled表示插件实例当前是否被禁用。它是插件实例模型中唯一可写的属性读写均受 Shell 层支持// packages/shell/src/model/plugin-instance.ts get disabled(): boolean { return this[pluginInstanceSymbol].disabled; } set disabled(disabled: boolean) { this[pluginInstanceSymbol].setDisabled(disabled); }读取时透传运行时对象的disabled字段写入时会调用运行时对象的setDisabled(disabled)即修改状态是有副作用的操作会真正影响插件的启用/停用逻辑而不是简单改一个标志位。与之等价的管理器级 API 是plugins.setDisabled(pluginName, flag)见 packages/designer/src/plugin/plugin-types.ts 中ILowCodePluginManagerCore.setDisabled。典型场景按用户权限或项目配置动态禁用某些内置面板。3.4 meta插件 meta 信息类型IPublicTypePluginMetameta承载插件的配置元数据是插件体系中最有信息量的属性其完整定义位于 packages/types/src/shell/type/plugin-meta.ts。Shell 实现中直接返回运行时对象的meta// packages/shell/src/model/plugin-instance.ts get meta() { return this[pluginInstanceSymbol].meta; }四、IPublicTypePluginMeta 元数据逐项解析IPublicTypePluginMeta定义了五个可选字段下面结合源码注释逐一说明。4.1 dependencies插件依赖声明/** * define dependencies which the plugin depends on */ dependencies?: string[];以数组形式声明本插件依赖的其他插件名。插件管理器据此进行依赖拓扑排序保证初始化顺序正确。dependencies是dep属性的元数据来源之一。4.2 engines引擎版本兼容声明engines?: { /** e.g. ^1.0.0 */ lowcodeEngine?: string; };声明插件兼容的引擎版本范围采用 npm 语义化版本semver规则例如^1.0.0表示兼容 1.x 系列。引擎在初始化插件时可据此做版本校验避免插件与引擎版本不匹配导致的运行异常。4.3 preferenceDeclaration偏好配置声明preferenceDeclaration?: IPublicTypePluginDeclaration;声明插件的偏好配置项preference用于在插件设置面板中展示可配置项。IPublicTypePluginDeclaration定义于 packages/types/src/shell/type/plugin-declaration.ts。声明后插件可通过上下文读取用户配置的偏好值。4.4 eventPrefix事件前缀这是元数据中行为影响最直接的字段。源码注释给出了清晰的规则/** * use common as event prefix when eventPrefix is not set. * strongly recommend using pluginName as eventPrefix * * eg. * case 1, when eventPrefix is not specified * event.emit(someEventName) is actually sending event with name common:someEventName * * case 2, when eventPrefix is myEvent * event.emit(someEventName) is actually sending event with name myEvent:someEventName */ eventPrefix?: string;要点总结未设置eventPrefix时插件通过event.emit(someEventName)发出的事件实际事件名会被加上common:前缀即common:someEventName设置eventPrefix: myEvent时实际事件名为myEvent:someEventName官方强烈建议使用插件名pluginName作为eventPrefix以避免不同插件的事件在common前缀下互相冲突实现事件隔离。4.5 commandScope命令作用域/** * 如果要使用 command 注册命令需要在插件 meta 中定义 commandScope */ commandScope?: string;如果插件要通过 command 能力注册命令则必须在meta中定义commandScope。该字段规定了插件注册的命令所属的作用域便于命令的统一管理与冲突规避。4.6 一个完整的 meta 示例const DemoPlugin (ctx) ({ init() { // 事件名实际为 DemoPlugin:hello ctx.event.emit(hello, { from: demo }); }, exports() { return { answer: 42 }; }, }); DemoPlugin.pluginName DemoPlugin; DemoPlugin.meta { dependencies: [PluginOutlinePane], engines: { lowcodeEngine: ^1.0.0 }, eventPrefix: DemoPlugin, // 推荐使用 pluginName 作为事件前缀 commandScope: demo, }; DemoPlugin.preferenceDeclaration { title: Demo 插件偏好, properties: [ { key: showTip, type: boolean, title: 是否显示提示, default: true, }, ], };五、底层运行机制从 PluginInstance 到 ILowCodePluginRuntimeIPublicModelPluginInstance是一个门面真正的运行时逻辑由ILowCodePluginRuntime承担。该运行时类型定义于 packages/designer/src/plugin/plugin-types.tsexport interface ILowCodePluginRuntimeCore { name: string; dep: string[]; disabled: boolean; config: IPublicTypePluginConfig; logger: IPublicApiLogger; meta: IPublicTypePluginMeta; init(forceInit?: boolean): void; isInited(): boolean; destroy(): void; toProxy(): any; setDisabled(flag: boolean): void; }从源码结构可以看到几个关键点运行时对象拥有init(forceInit)、destroy()、isInited()等生命周期方法而公开模型刻意不暴露这些内部方法保持对外 API 的克制与稳定disabled的写入最终落到setDisabled(flag)说明禁用是一个可恢复的状态切换运行时通过IPublicTypePluginConfig定义于 packages/types/src/shell/type/plugin-config.ts描述插件的init、destroy、exports三个生命周期钩子init(): Promisevoid | void插件初始化入口destroy?(): Promisevoid | void插件销毁清理exports?(): any对外暴露的公共 API可通过插件实例访问。因此当你通过plugins.get(name)拿到IPublicModelPluginInstance时实际看到的是运行时状态的一层稳定投影身份pluginName、依赖dep、状态disabled与元数据meta。六、实战综合使用插件实例模型结合以上内容给出一个完整的实战片段读取、校验并控制插件实例。import { IPublicModelPluginInstance } from alilc/lowcode-types; function inspectPlugin(instance: IPublicModelPluginInstance | null): void { if (!instance) { console.warn(插件不存在); return; } // 1. 身份信息 console.log(插件名:, instance.pluginName); // 2. 依赖信息打印依赖的其他插件 console.log(依赖插件:, instance.dep?.join(, ) || (无)); // 3. 状态读写禁用 / 恢复 if (!instance.disabled) { instance.disabled true; // 等价于 plugins.setDisabled(name, true) console.log(${instance.pluginName} 已禁用); instance.disabled false; // 恢复启用 } // 4. 元数据依赖、引擎版本与事件前缀 const meta instance.meta; console.log(声明的依赖:, meta.dependencies); console.log(兼容引擎版本:, meta.engines?.lowcodeEngine); console.log(事件前缀:, meta.eventPrefix ?? common); console.log(命令作用域:, meta.commandScope); } // 使用 const plugin editor.get(plugins).get(DemoPlugin); inspectPlugin(plugin);使用建议读取优先、写入谨慎pluginName、dep、meta为只读唯一可写的disabled会触发真实的启停逻辑改动前请确认业务时序善用dep与meta.dependencies依赖声明是插件管理器保证初始化顺序的依据插件间协作务必显式声明事件前缀用插件名遵循源码注释中strongly recommend using pluginName as eventPrefix的建议避免common:命名空间下的跨插件事件污染。七、小结PluginInstance 模型以四个精简属性pluginName、dep、disabled、meta完整刻画了一个插件实例的身份、依赖、状态与元数据。它既是插件管理 APIpackages/shell/src/api/plugins.ts对外返回的统一视图也是底层运行时packages/designer/src/plugin/plugin-types.ts的安全门面。理解这一模型是编写高质量 lowcode-engine 插件、进行插件间依赖编排与动态启停控制的基础。进一步阅读可参考 插件注册与生命周期 以及插件实例相关的模型 API 文档并结合 plugin-meta 类型定义 验证各元数据字段的实际约束。【免费下载链接】lowcode-engineAn enterprise-class low-code technology stack with scale-out design / 一套面向扩展设计的企业级低代码技术体系项目地址: https://gitcode.com/GitHub_Trending/lo/lowcode-engine创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考