Electron 嵌入的页面中注入的是 preload.js
通过在标签中给 prelaod赋值,这里提到了 file://前缀,以及静态目录 static 怎么获取

实际代码,其中__static就是我们存放静态文件的地方,这个 static 是 electron 源代码根目录下的文件,最终打完包后会放在 dist/electron/ 根目录下

而__static 是在index.html 中进行赋值的
这里看,因为渲染进程会直接启动 index.html 这个文件,同时渲染进程又能调用 node.js 库,因此这里拿到的__static就是安装目录下的 static,因为这个 static 在asar压缩包里,所以这里就必须使用 file://{__static},否则读不到asar 的虚拟目录路径

ChatGPT 虚拟目录概念:asar 可以进行解压,具体执行命令即可,后面详细研究后,再发文章
虚拟目录是一种将文件和文件夹组织成虚拟结构的方式,这些文件和文件夹在物理存储介质上(如硬盘)可能并不按照实际目录结构存储。在计算机科学和软件开发中,虚拟目录的概念是指一种将文件或数据组织成层次结构,使其看起来像是存储在目录结构中,但实际上可以是物理存储介质上的一个单一文件或数据库。
在 Electron 中,asar 存档就是一种虚拟目录的实现方式。asar 存档将应用程序的文件和文件夹组织成虚拟目录结构,这些文件和文件夹存储在一个单一的存档文件中,而不是以普通的文件和目录的形式存在于文件系统中。
这种虚拟目录结构的优点是:
减小应用程序的体积:asar 存档允许将所有文件打包成一个文件,减小了应用程序的体积,使得分发和部署更加方便。
加速文件访问:由于文件被打包成一个存档文件,文件的加载速度更快,因为它们可以被一次性加载到内存中,而不需要多次访问物理存储介质。
组织和保护文件:asar 存档允许将文件和文件夹组织成有层次结构的虚拟目录,这有助于更好地组织和保护应用程序的文件。
虚拟目录的概念使得开发者能够以更灵活的方式管理文件和数据,同时提高应用程序的性能和可维护性。在 Electron 中,asar 存档用于将应用程序文件组织成虚拟目录结构,以提高应用程序的性能和效率。
webview 与被嵌入的渲染进程通信
preload.js 就像插件的 content script 与网页的原生的环境还是隔离的,两个环境的变量互不影响,比如在 preload.js给 window 追加一个函数A,在原生网页中window.A 是 undefined,所以 preload.js 是沙盒环境。
但 preload.js(被注入网页中)中可以与其嵌入的 webview 容器进行通信,具体就是监听 ipc-message,接收渲染进程的消息,同时 webview还能通过 webview.send('ping') 给preload.js环境发送消息,这样就实现了 webview 容器中的网页与 webview 之间的通信过程
// In embedder page.
const webview = document.querySelector('webview')
webview.addEventListener('ipc-message', (event) => {
console.log(event.channel)
// Prints "pong"
})
webview.send('ping')
preload.js 所在的页面叫 guest page(访客页)
// In guest page.
const { ipcRenderer } = require('electron')
ipcRenderer.on('ping', () => {
ipcRenderer.sendToHost('pong')
})
webview 容器内页面 与 preload.js 通信
如果在 guest page 中用 `webview.executeJavaScript(js代码)` 这样在 window.A下就可以访问到,但是两个环境之间有怎么进行通信呢?
参考插件的content script 和 inject 的通信方式:
1. 一是通过 window.postMessage 和 window.addEventListener("message", callback),这一种要把所有的事件都在一个 message 函数中处理,比较麻烦,如果不使用反射机制,就会将代码写得很长,有很多 if 判断;
2. 二是通过事件 window.dispatchEvent(new CustomEvent('INJECT_READY')) 和 window.addEventListener("INJECT_READY", callback) 这种方式就好一些,可以将监听事件封装成具体的函数,引入处理,代码比较隔离
3. electron 还给出了一种可以直接从 preload.js暴露函数给 window 的方式,这种非常方便:

通过这样进行调用
await window.electron.getAttachment(local_path, attachment.oss_path)
webview 和主进程通信
1. 借助被嵌入的渲染进程与主进程通信,这个就不细说了。
// 主进程代码
ipcMain.on("win-auto-update", (event, arg) => {})
// 渲染进程代码
ipcRenderer.send("win-auto-update")
// 渲染进程与渲染进程通信
ipcRenderer.sendTo(wid, "win-auto-update", {...})
// 渲染进程监听消息
ipcRenderer.on("win-auto-update", (event, args) => {})
// event 对象中能够获得消息的来源是从哪个渲染进程发过来的
解决一切苦厄的终极通信
1. 在主进程中启动 Websocket 、Http 服务,Http 服务可以帮助用来从主进程访问本地数据库,Websocket 可以用来直接接收 webview preload 还是executeJavaScript,都可以通过 websocket 客户端直连主进程,主进程收到后,可以进行转发操作,过程中可以使用 Promise实现 await wsRequest 方式。这样整个链路就缩短为只需要直连任何一个进程的概念,就不用转来转去了,同时还能用 await 保证逻辑执行顺序,不因为通信延时无法控制 UI 表现层问题。
具体我后面整理OK 后,再发一个代码 Demo 吧,有提前需要的也可以私信我。
465

被折叠的 条评论
为什么被折叠?



