API v1
Documentation/开发指南

调试插件

根据插件启动、动作执行或页面显示的问题定位原因。

Plugin API v1

Documentation content is currently available in Simplified Chinese.

在开发插件的过程中遇到报错或运行异常很正常,别慌!飞块为你提供了完善的诊断排查机制。

高效排查的关键是精准定位阶段:先分清问题究竟是发生在插件启动阶段、动作执行阶段,还是前端页面渲染阶段。逐层剥离往往能让你在几分钟内准确定位根因,避免盲目修改代码或配置文件。


#1. 插件无法启动或闪退

当你在拓展管理中尝试启用插件却提示失败时,通常由以下几种原因引起:

#症状一:提示找不到文件或模块

  • 排查方向:仔细核对 manifest.json 中的 main、page 路径与项目实际产物结构。
  • 常见根因:如果你使用 TypeScript 开发,请确认已运行 flyon build 生成了对应的编译文件(例如 dist/index.js),且清单中的 main 指向的是编译产物而非源码。

#症状二:提示“注册不一致”或未找到声明的处理函数

  • 排查方向:检查清单中声明的每个动作、状态或服务 ID,是否都在 definePlugin() 中注册了同名处理函数。ID 区分大小写且必须完全匹配。

#症状三:直接使用 node index.js 启动报错

  • 排查方向:插件后台依赖飞块宿主注入的上下文环境(如 process.env.FLYONDECK_SDK_PATH)。切勿在终端直接用普通 Node 启动插件入口,请通过飞块桌面端的“加载开发文件夹”或运行 flyon dev 进行热联调。

💡 排查小妙招:在 onStart() 或文件顶层加入 console.log(),结合 flyon logs 或桌面端控制台日志,能清晰还原插件启动时的每一个步骤。


#2. 插件间依赖与协作报错

当你的插件声明了依赖其他插件提供的能力(如服务或数据源)时,请按照以下规则排查:

  • 缺少提供方插件:必须先在飞块中安装并启动提供方插件,消费方才能正常建立连接并调用。
  • 版本不兼容:
    • 检查 manifest.json 中 dependencies[pluginId] 填写的 SemVer 版本范围是否涵盖提供方的实际 version;
    • 检查 uses 中声明的服务 ID 和整数版本号,是否与提供方的 contributes.services 契约严格一致。
  • 循环依赖警告:宿主出于安全稳定考量,禁止插件间产生互相依赖的死锁环。如遇循环依赖,请抽离公共能力的第三方插件作为基础提供方。
  • 卸载与更新顺序:当提供方正在被多个消费方使用时,无法直接强制停用或替换。请先停用或卸载消费方,再更新提供方插件。

#3. 动作执行报错或没有反应

当你按下实体按键或运行工作流时,动作抛出异常或表现不如预期:

#症状一:提示数据类型不匹配(如“类型应为 string”)

  • 排查方向:检查前端传入的参数类型是否与清单中的 argsSchema 一致。例如,数字 "42"(字符串)与 42(数值)在 Schema 校验中是严格区分的。若需数字输入,请在 Schema 中声明为 type: "number" 或 integer。

#症状二:提示“无效参数”或找不到字段

  • 排查方向:对照 Action.argsSchema 参考 检查参数字段命名。建议在动作处理函数的开头打印参数对象:
    javascript
    console.log("收到动作参数:", JSON.stringify(args, null, 2));

#症状三:流程中后续步骤取不到上一步的返回值

  • 排查方向:确认函数的 return 返回值字段名是否与清单中的 outputSchema 丝毫不差。推荐在流程末尾加入一个内置的“输出”动作,在内容中绑定前一步的“步骤结果”进行打印验证。

#4. 超级块页面空白或数据未刷新

超级块的前端页面涉及浏览器渲染与后台 IPC 通信,建议按如下次序分步排错:

  1. 检查页面 SDK 是否正确加载:
    打开开发者工具(桌面端支持右键检查元素或通过远程调试端口),查看 Console 控制台是否报错。主页面 HTML 头部必须正确引入官方 SDK 脚本:
    html
    <script src="/api/plugin-sdk/widget-page-v1.js"></script>
  2. 核对状态来源 ID(Source ID):
    确认 manifest.json 中的 stateSource、后台调用的 context.states.publish(),以及前端页面所监听的来源 ID 是否保持三方统一。
  3. 核查实例标识(适用于 widget-instance 作用域):
    如果超级块使用的是私有实例状态,后台向实例推送数据时必须携带有效的 (deviceId, screenId, blockId)。可以在后台打印 context.widgets.instances() 的返回值,确认当前实例是否已成功被宿主识别并分配。
  4. 区分目录预览与实际放置:
    未放置在画布上的组件位于选择目录中,此时没有真实的实例上下文。请参考最佳实践,在无真实实例时展示带有“示例”标注的演示内容,放置到画布后再接收真实状态。

#5. 网络请求受阻与跨域失败

由于飞块严格的安全机制,插件发起的所有外网请求均受到安全白名单的保护:

  • 通过后台发起请求(context.network.getJson):
    如果提示无权请求,请检查 manifest.json 的 permissions 数组是否已包含 "network.getJson",且目标域名已精确添加到 networkOrigins 白名单中。
  • 通过前端页面直接 fetch():
    如果是超级块 HTML 页面直接调用接口,请检查清单中的 widgetConnectOrigins 是否已放行对应源,并确认目标接口服务器已开启正确的 CORS 响应头。

📚 深入参考:更多关于权限范围与网络安全规则的详细配置,请查阅权限与联网参考文档。