1. 完整示例
插件化手册
  • FH2 插件开发手册
    • 产品简介
    • 典型场景
    • 发版说明
    • 快速开始
      • 快速开始总览
      • 第一个插件
      • 后端插件
      • 全栈闭环
    • AI辅助开发
      • AI 开发 Skill
      • 安装与复验
      • 第一个工程
      • 真实需求示例:现场问题上报
      • 改造已有工程
      • 调试与交付
    • 开发指南
      • 开发指南
      • 基础概念
        • 基础概念总览
        • 什么是插件开发
        • 平台架构
        • 前端宿主、扩展点与能力
        • 后端运行时、入口与权限
        • 开发流程
        • 安全与隔离
        • 支持范围与问题反馈
      • 开发指南
        • 开发指南总览
        • 前端插件
          • 前端插件深度指南
          • 前端工程结构
          • 插件清单(fh2-plugin.json)
          • 入口与生命周期
          • 界面与状态
          • 多宿主插件
          • 跨宿主通信服务
          • HTTP、WebSocket 与事件
          • 存储、Blob 与定时器
          • 工具链与本地调试页面
        • 后端插件
          • 后端开发深度指南
          • 后端插件的结构
          • 后端源清单 fh2-plugin.json
          • HTTP 接口处理函数
          • 消息订阅与事件处理函数
          • ctx 与能力注入
          • 数据存储与缓存
          • 流程编排
          • 触发方式
          • 连接外部系统
          • 流程编排练习(DAG)
        • 前后端协作
          • 前后端协作总览
          • 前后端共享契约
          • 端到端幂等
          • 事件、通知与状态
          • 统一错误模型
          • 链路标识与诊断日志
        • 完整练习
          • 环境准备
          • 第一个前端插件
          • 第一个后端插件
          • 第一个全栈插件
      • 能力总览
        • 能力地图
        • 能力可用性矩阵
        • 前端能力
          • 平台通用能力
            • 平台通用能力总览
            • 基础运行时:HTTP、事件、WebSocket 与存储
            • 导航、位置与通知
            • 弹窗、音频与剪贴板
            • 地图能力
            • 项目设备能力
            • WPMZ 与航线预览
            • 受控对象上传
          • 项目宿主
            • 项目宿主总览
            • 项目上下文
            • 项目侧边栏入口
            • 项目插件路由
            • 项目工作区
          • 消息宿主
            • 消息宿主总览
            • 消息告警弹层
            • 消息导航与通知
          • 计划库宿主
            • 计划库宿主总览
            • 计划库表单上下文
            • 计划库表单扩展
            • 校验、提交与 `biz_ext`
          • 驾驶舱
            • 驾驶舱插件能力总览
            • 驾驶舱扩展点
            • 上下文与遥测
            • 相机、检测与 AI
            • 场景几何与直播指针
            • 飞控、云台与任务
            • 驾驶舱平台事件
        • 后端能力
          • 后端能力地图
          • 后端能力总览
          • 配置、受管出网与集成连接
          • 事件与流程
          • 飞行任务与违停巡逻
          • 数据存储
          • 媒体与前端通知
          • 资源租约
          • 作业、目标轨迹与视频处理
      • 调试与测试
        • 调试与测试总览
        • 快速入门排错
        • 本地开发
        • Web IDE:打开工程与保存改动
        • 工作流编辑器:节点、接线与交付
        • 知识与 MCP:先判断需要哪一层事实
        • 前端本地调试
        • 后端运行时与流程调试
        • 模拟数据与测试数据
        • 集成测试与 E2E
        • 日志与链路追踪
        • 常见问题排查
      • 完整示例
        • 示例与案例总览
        • 项目侧边栏与工作区
        • 消息告警卡片
        • 计划表单任务清单
        • 驾驶舱动作与左侧面板
        • 最小后端插件
        • 最小全栈插件
        • 多宿主插件实战
        • 事故快处
        • 交通抓拍
        • 违停巡逻完整案例
      • 构建发布与安全
        • 构建、发布与安全
        • 质量门禁
        • 行业包构建与打包
        • 能力版本发布
        • 安装、升级与回滚
        • 安全基线
      • API参考
        • API 参考总览
        • 前端
          • 前端 API 参考
          • 前端插件清单结构
          • 前端 SDK API
          • 前端扩展点目录
          • 前端能力目录
          • 前端平台事件目录
          • 跨宿主通信服务 API
          • 工具链命令行参考(`fh2-plugin`)
        • 后端
          • 后端 API 参考
          • 后端插件源清单
          • 后端 HTTP 接口参考
          • 后端事件消费参考
          • 后端脚本上下文(`ctx`)
          • 后端数据存储
          • 流程编排语言
          • 流程触发器参考
          • 后端能力目录
          • 后端 HTTP API
        • 共享契约
          • 共享契约参考
          • 类型与契约目录
          • 错误模型
          • 版本兼容性
      • 附录
        • 错误码
        • 术语表
        • 常见问题
  1. 完整示例

多宿主插件实战

这是一份集成说明,不是完整工程:讲同一个插件怎样在驾驶舱、计划、消息和项目四个宿主分发代码,再通过服务交换数据。先完成一个单宿主练习,按实际需求增加第二个宿主;不要一次复制下面的清单就期待四处界面全部出现。
fh2-plugin-sdk 是插件开发 SDK;下文模块名用于说明,实际导入路径保留生成工程配置。模块名不表示已发布的 npm 包名。

这个示例做什么#

一个插件包,四个宿主各挂一个功能;每个宿主只加载自己的那部分代码。
总入口按 ctx.host.id 分发到各宿主的激活逻辑,互不干扰。
演示插件内跨宿主通信的标准方式:跨宿主通信服务(类型化契约),而不是直接 import 另一个宿主的运行对象。

关键代码讲解#

清单:同时声明多个宿主的扩展点#

fh2-plugin.json:
{
  "id": "exp_multi_host",
  "name": "多宿主示例",
  "version": "0.1.0",
  "entry": "./plugin.js",
  "extensions": [
    { "id": "hello-action", "point": "cockpit.ui.toolbar-actions" },
    { "id": "hello-panel", "point": "cockpit.ui.left-panel" },
    { "id": "hello-plan", "point": "plan.form-extensions", "planType": "all" },
    { "id": "hello-message", "point": "message.alert-popups" },
    { "id": "hello-project", "point": "project.sidebar-actions", "path": "/hello-project" }
  ],
  "views": {
    "hello-cockpit": { "entry": "./views/hello-cockpit.js" },
    "hello-plan": { "entry": "./views/hello-plan.js" },
    "hello-message": { "entry": "./views/hello-message.js" },
    "hello-project": { "entry": "./views/hello-project.js" }
  }
}
各宿主贡献的具体写法见前面的单宿主示例:驾驶舱按钮、计划表单、消息告警、项目侧边栏。

总入口:只做分发#

// src/plugin.ts
import { definePlugin } from 'fh2-plugin-sdk'

export default definePlugin({
  async activate (ctx) {
    switch (ctx.host.id) {
      case 'cockpit':
        return (await import('./hosts/cockpit/activate')).activate(ctx)
      case 'plan':
        return (await import('./hosts/plan/activate')).activate(ctx)
      case 'message':
        return (await import('./hosts/message/activate')).activate(ctx)
      case 'project':
        return (await import('./hosts/project/activate')).activate(ctx)
      default:
        ctx.logger.warn(`[multi-host] 未知宿主: ${ctx.host.id},跳过激活`)
        return undefined
    }
  },
})
要点:
总入口不导入 Vue、不访问 DOM,保持轻量。
每个宿主的逻辑放在独立文件里动态导入,避免一个宿主加载其他宿主的组件和能力。
每个宿主是独立运行时、独立激活:卸载驾驶舱不影响另外三个宿主。

跨宿主通信服务#

先声明契约:
// src/services/hello-dispatch.ts
import { definePluginService } from 'fh2-plugin-sdk'

export interface HelloDispatchInput {
  readonly executionId: string
  readonly title: string
}

export interface HelloDispatchService {
  presentDispatch (input: HelloDispatchInput): { readonly accepted: boolean }
}

export const helloDispatchService = definePluginService<HelloDispatchService>('hello-dispatch')
提供方(比如消息宿主激活时):
// src/hosts/message/activate.ts
import { helloDispatchService } from '../../services/hello-dispatch'

export async function activate (ctx) {
  // ...注册告警卡片(写法见消息告警示例)

  await ctx.services.provide(helloDispatchService, {
    presentDispatch (input) {
      ctx.logger.info('收到派遣展示请求', { executionId: input.executionId })
      return { accepted: true }
    },
  })
}
消费方(任何宿主):
const client = await ctx.services.connect(helloDispatchService)
const result = await client.presentDispatch({ executionId: 'e-1', title: '警情派遣' })
要点:
服务按契约通信,方法都是 Promise。connect() 返回稳定逻辑 Client,不等待具体 Provider;Provider 缺席或卸载时,业务方法抛 SERVICE_UNAVAILABLE,事件订阅在 Provider 重建后自动恢复。
宿主之间不要共享模块级可变状态:每个宿主是独立运行时,直接共享状态会错乱。需要共享就走跨宿主通信服务,或者各自从后端读权威数据。

怎样组装并验证#

先完成环境准备,再创建工程。保留生成工程的依赖、构建配置和实际 SDK 导入路径,按本页合并清单并修改业务实现;新增文件的 SDK 导入路径沿用模板。按单宿主示例补齐四份激活逻辑、界面契约、入口和组件后,可在本地调试页面验证分发与跨宿主通信服务;各宿主的真实业务边界仍以单宿主示例为准。
在确认的业务父目录运行创建向导,选择「1=前端插件」,Plugin ID 输入 exp_multi_host,其余项按默认值确认并选择立即安装。命令只要求终端能直接运行 fh2-plugin;未注册全局 CLI 时,把它替换为开发者工具目录中 packages/fh2-plugin-toolchain/bin/fh2-plugin.mjs 的实际路径:
验证步骤:
1.
默认团队页只有项目和消息宿主;进入计划表单后再验证计划贡献,进入虚拟驾驶舱后再验证驾驶舱贡献。四个宿主不同时显示在一个页面上。
2.
在对应页面分别验证按钮、面板、告警卡和侧栏;每个宿主只应显示自己声明的贡献。上方清单的界面 ID 必须与实际文件、注册契约一致。
3.
在顶部工具栏打开「Host」,卸载当前已挂载的驾驶舱;项目和消息仍保持挂载。此时计划宿主不在当前页面拓扑中,不应要求它保持挂载。
4.
点击实际入口「恢复页面 Host」,只补回当前页面缺少的宿主;已经挂载的项不重载。重新打开对应界面,确认没有重复贡献。
5.
逐个卸载已挂载宿主,在诊断面板核对相关资源释放。示例需要你补齐四份激活与界面文件;本页不以清单校验成功证明这些业务已接线。

常见问题#

现象原因与处理
只有驾驶舱生效总入口的 switch 没覆盖其他宿主,或清单没声明对应扩展点
某个宿主失败被当成整个插件失败多宿主插件可以处于"部分降级"状态;看健康状态里的 activeHosts / failedHosts
宿主之间状态错乱有代码在宿主间直接共享模块级状态;改用跨宿主通信服务或后端权威数据
跨宿主通信服务调用没反应Provider 缺席时 connect() 仍可成功,业务方法会抛 SERVICE_UNAVAILABLE;核对服务 ID 与契约,或等 Provider 重建后重试业务方法
部分宿主行为不一致项目/消息/计划宿主是 iframe 隔离运行时,检查跨运行时序列化和 CSP

延伸阅读#

多宿主插件:宿主路由与生命周期详解。
跨宿主通信服务:provide / connect 完整说明。
宿主与能力模型:四个宿主分别提供哪些能力。
修改于 2026-10-22 03:40:00
上一页
最小全栈插件
下一页
事故快处
Built with