项目中JSSDK封装方案

前言

这是入职之后,在公司项目中,梳理的jssdk封装的方案,其中一些方法例如:ipcRenderer.sendTo()已经在新版的eletron中弃用,其中的方案仅供学习。有不对的地方也欢迎各位大佬指正

弃用:ipcRenderer.sendTo()

ipcRenderer.sendTo() 已被弃用。 可以通过在渲染器之间设置一个MessageChannel 来替换它。 IpcRendererEventsenderIdsenderIsMainFrame 属性也已被弃用

后面,项目中还引入了模块联邦,这一块还没有梳理到,我会在之后补充进文档当中。

一、SDK工作流程图

什么是jssdk?它描述是一个工具集合,能够帮助我们快速调用各种能力,其包含了各种api,有自己的api文档和调用案例。

二、SDK整体架构设计

sdk主要配置路径/src/11-renderer/_public/sdk

其目录架构组成为:

2.1、通信桥接层

在/msgbridge.ts文件下,这里负责处理收到的postmsg,处理不同窗口间的postMessage通信,同时支持webView和BrowserView等场景(还有模块联邦)的通信,进行统一的消息处理、参数处理和api鉴权。

webView

ts 复制代码
// 处理发送postmg
// containerId:目标窗口id
// msgdata:传递的参数
export function handlePostMessage({ msgdata, containerId }: { msgdata: any; containerId: any }) {
    const { url, webview } = getWebviewUrl(containerId);
    webview && webview.contentWindow.postMessage(msgdata, url);
}

BrowserView

ts 复制代码
function handleBrowserViewMessage({ msgdata, containerId }: { msgdata: any; containerId: any }) {
    window.ELECTRONCHANNEL &&
        window.ELECTRONCHANNEL.electronBrowserviewSendToData({ ...msgdata, view_id: containerId });
}

2.2. 状态管理层

/redux.js 进行状态管理适配,可以根据不同的apicaller动态加载对应的redux模块

2.3. API层

csharp 复制代码
api/
 --biz/            # 业务相关API
    -- util/       # 工具类API
    -- chat/       # 聊天相关
    -- contact/    # 联系人相关
    -- group/      # 群组相关
    -- navigation/ # 导航相关
 --device/         # 设备相关API
 --runtime/        # 运行时API
 --primary/        # 基础API
 --noPoint/        # 免鉴权API
 --util/           # 通用工具

2.4. 文件处理系统

/file目录下封装了对文件的处理的方法,比如视频转码、视频播放、文件预览、文件下载等功能

2.5. 事件系统

在目录/yach-event下,封装了ai助手调用、addContentToEditor、toggleAddPrompt等方法。

三、如何建立通信

通信的建立包括四个步骤:preload脚本注入、H5调用、Yach接收调用、H5接收返回。

大致流程图如下:

从两种情况出发,webView和BrowserView,在我们注入脚本的时候,sendTo和sendToHost两个方法的应用场景也不同。

3.1 sendTo

官方:ipcRenderer.sendTo() 已被弃用。 可以通过在渲染器之间设置一个 MessageChannel 来替换它。

需要明确指定目标渲染进程的容器id

javascript 复制代码
ipcRenderer.sendTo(win.id, '事件名', JSON.stringfy(data))

大致通信过程

1、主进程获取容器id并且发送给需要通信的进程

ts 复制代码
// 主进程
const winA = new BrowserWindow();
const winB = new BrowserWindow();
// 向 winA 传递 winB 的 ID
winA.webContents.send('target-id', winB.webContents.id);

2、渲染进程A向进程B发送消息

ts 复制代码
//渲染进程A
ipcRenderer.on('target-id', (event, targetId) => {
  ipcRender.sendTo(targetId, 'test', '这是A发送的消息')
})

3、渲染进程B接收消息

ts 复制代码
//渲染进程B
ipcRenderer.on('test', (event, message) => {
  console.log(message)//输出这是A发送的消息
})

3.2 sendToHost

无需指定目标容器id,默认发送给当前渲染进程的"主容器"(通常是主进程创建的容器页面)

arduino 复制代码
ipcRenderer.sendToHost('事件名', '消息');

大致通信流程

1、渲染进程

ts 复制代码
// 渲染进程(网页)
ipcRenderer.sendToHost('test', '这是渲染进程的消息');

2、主进程进行监听并且处理

ts 复制代码
const win = new BrowserWindow({
  webPreferences: { nodeIntegration: false}// 限制渲染进程权限
});
//监听sendToHost发送的消息
wind.webContents.on('ipc-message',(event, channel, args) => {
  if(channel === 'test'){
    //处理并返回结果
    event.sender.sendToHost('result', {list: [...]})
  }
})

3、渲染进程接收宿主消息

ts 复制代码
//渲染进程
ipcRenderer.on('result', (event, data) => {
  console.log(data); //输出: 主进程返回的list
})

3.3 webView

webView是一个嵌入在渲染进程中的"子浏览器窗口",内部运行独立的渲染进程,且具有严格的沙箱隔离。通常使用senToHost方法。

webView内部页面的"宿主"是外层的渲染进程或者主进程,sendToHost设计的初衷就是让子页面向宿主发送消息,无需关心宿主的具体窗口id,简化通信链路。

3.4 browserView

browserView是由主进程创建、直接挂载到主窗口的"原生视图",没有独立的沙箱,其通信通过主进程的webContents直接交互,通常使用sendTo方法

browserView是由主进程管理,其webContent有明确的id,可以通过browserView。webContent.id获取。主进程或者其他渲染进程可通过sendTo(id, message)直接向其发消息。

相关推荐
anyup10 小时前
2026第一站:分享我在高德大赛现场学到的技术、产品与心得
前端·架构·harmonyos
BBBBBAAAAAi10 小时前
Claude Code安装记录
开发语言·前端·javascript
xiaolyuh12311 小时前
【XXL-JOB】 GLUE模式 底层实现原理
java·开发语言·前端·python·xxl-job
源码获取_wx:Fegn089511 小时前
基于 vue智慧养老院系统
开发语言·前端·javascript·vue.js·spring boot·后端·课程设计
毕设十刻11 小时前
基于Vue的人事管理系统67zzz(程序 + 源码 + 数据库 + 调试部署 + 开发环境配置),配套论文文档字数达万字以上,文末可获取,系统界面展示置于文末
前端·数据库·vue.js
anyup11 小时前
从赛场到产品:分享我在高德大赛现场学到的技术、产品与心得
前端·harmonyos·产品
前端工作日常11 小时前
我学习到的A2UI的功能:纯粹的UI生成
前端
Jing_Rainbow11 小时前
【 前端三剑客-37 /Lesson61(2025-12-09)】JavaScript 内存机制与执行原理详解🧠
前端·javascript·程序员
桌面运维家11 小时前
vDisk配置漂移怎么办?VOI/IDV架构故障快速修复
网络·架构
刘立军12 小时前
如何选择FAISS的索引类型
人工智能·算法·架构