跳转到主要内容

插件依赖与互调用

插件可以依赖其他插件(前置插件),并在插件之间互相调用方法。典型的场景:MarkdownLib 作为库插件提供 renderMarkdown 方法,其他插件依赖它并在页面里调用。

一、声明依赖

在 manifest 的 dependencies 字段声明:

二、必装前置(optional: false)

  • 安装时:缺失或版本不满足 → 拒绝安装,后端返回 PLUGIN_MISSING_DEPENDENCY(400),错误消息列出缺失项
  • 启动时:前置插件未安装或未启用 → 该插件跳过激活并置为 disabled
  • 用户需先安装前置插件,才能安装依赖它的插件

三、可选前置(optional: true)

  • 安装 / 激活不强制检查
  • 仅当前置插件存在且已启用时,callPlugin 才能调用其方法
  • 前置缺失时调用 callPlugin 报错,但插件本身正常启用
  • 调用可选前置的方法时务必 try/catch:

四、库插件惯例(被依赖方)

库插件(如 MarkdownLib)通常:
  • 不声明 contributes.menuItems → 不会在侧边栏创建任何入口
  • 只声明 entry.frontend(哪怕是一个空白页)+ 激活时 registerMethod
  • permissions 至少包含 config:write(registerMethod 需要)
库插件的 layers 用纯 ["l3"](内联)或 ["l2", "l3"](沙箱)均可。要点:
  • 激活取决于 entry.frontend 是否存在 + 用户是否启用,与 layers 无关
  • 必须声明 entry.frontend:只有声明了 frontend 的插件才会被激活(从而执行脚本、注册方法)。省略 frontend 的插件不会被激活,方法也就无法注册 见 layers 图层定义。

五、提供方:注册方法

被依赖插件在激活后的页面脚本中注册方法:
  • registerMethod(method, fn):fn 返回值为值或 Promise(异步方法同样支持)
  • 一个插件可注册多个方法
  • 插件停用时自动注销全部方法
  • 权限:config:write

六、调用方:调用方法

  • 调用签名:callPlugin(插件Id, 方法名, ...参数)
  • 权限:network:fetch
  • 支持调用异步方法(提供方返回 Promise 时直接 await)

七、激活顺序

启动器启动时对被依赖插件先排序激活(拓扑排序 sortByDependencies),保证依赖方激活时前置插件已就绪并注册好方法。因此无需关心 manifest 里的声明顺序。

八、错误处理

完整流程

  • 用户安装 MarkdownLib → 成功(无依赖)
  • 用户安装 AI 助手 → 后端检查依赖:markdown 已装且 1.2.0 >= 1.0.0 → 成功
  • 启动器启动 → 先激活 MarkdownLib(注册 renderMarkdown)→ 再激活 AI 助手
  • AI 助手 callPlugin('top.qomicex.markdown', 'renderMarkdown', md) → 主窗口 __pluginRegistry 中转 → 返回渲染结果