Electron
Electron是由github开发,用HTML/CSS/JS来构建的跨平台桌面端应用 Electron通过将Chromium和Node.js合并到同⼀个运行时环境中,并将其打包为Mac, Windows和Linux系统下的应⽤来实现这⼀目的。
Chromium: 是一个开源的Web浏览器项目,它是Google Chrome浏览器的基础 Chromium用于渲染应用程序的界面,支持HTML、CSS和JavaScript,使得应用的用户界面看起来和行为类似于Web应用 Node.js提供了与操作系统交互的能力
- electron开发桌面端有很大的优势
- 前端工程化、前端的第三方库、前端生态
- 使用前端语言开发
- 一套代码开发 支持3个平台通用
缺点
- 性能差、体积大
- 可能用户体验比较差, 程序运行缓慢
镜像加速
环境搭建
- 安装electron包
npm init -y
npm install electron --save-dev
- package.json的script
- "start": "electron ."
创建页面
- 在Electron中,各个窗口显示的内容可以是本地HTML文件,也可以是一个远程url。
快捷键
- Electron 应用中打开控制台的方法
- 快捷键:按 Ctrl + Shift + I(Windows/Linux)或 Cmd + Option + I(Mac)
- 菜单栏:点击 视图 → 开发者 → 开发者工具
调试技巧
- 1、nodemon
- 可以监听electron主进程文件变化并自动重新启动进程
- 2、vscode调试可以配合nodemon
- 每次调试都可以自动启动进程
vscode debug调试配置
{
"version": "0.2.0",
"configurations": [
{
"name": "Debug Main Process",
"type": "node",
"request": "launch",
"cwd": "${workspaceFolder}",
"runtimeExecutable": "${workspaceFolder}/node_modules/.bin/electron",
"windows": {
"runtimeExecutable": "${workspaceFolder}/node_modules/.bin/electron.cmd"
},
"args" : ["."],
"outputCapture": "std"
}
]
}
控制渲染进程样式
- 1、通过css控制
- 2、BrowserWindow配置项
- transparent: true
- 设置透明
- frame:false
- 设置无框、无标题栏
- frame用于设置窗口外壳
- transparent: true
- 3、BrowserWindow方法,内置了操作窗口的样式方法
- win.setAspectRatio 控制窗口比例
- win.setSize 控制窗口大小
- .....
使用css控制拖拽
默认情况下, 无边框窗口是不可拖拽的。 应用程序需要在 CSS 中指定 -webkit-app-region: drag
- 需在
BrowserWindow的构造中将frame参数设置为false, 设置为无框窗口,才能让body拖动- 设置了frame表示窗口为无框、无标题栏,无法使用标题栏来拖动,只能通过body
- 注意有些组件需要设置不能拖动,否则原有的一些事件无法触发
#js
const win = new BrowserWindow({ frame: false })
# style.css
body {
-webkit-app-region: drag; // 使该区域能拖拽
}
// 注意有些组件需要设置不能拖动,否则原有的一些事件无法触发
textarea,button {
-webkit-app-region: no-drag;
}
body {
width: 100vw;
height: 100vh;
}
渲染进程使用Node模块
Electron为了安全性的考虑,是渲染子进程不能使用node.js模块的,如果要在渲染进程中使用node.js模块,需要在创建主进程时进行设置
- 1、配置webPreferences的 nodeIntegration设置为true, 【启用node模块】
- 2、设置contextIsolation: false 【控制渲染进程 是否为沙箱模式】
- 控制渲染进程中是否启用沙箱模式。如果设置为 true,则渲染进程中的 JavaScript 代码将运行在一个独立的沙箱环境中,无法访问 Node.js 模块和原生 API,只能通过 Electron 提供的 API 与主进程进行通信。这可以提高应用程序的安全性,防止恶意代码对系统进行攻击
消息通道
- 消息通道MessageChannel,可以在不同渲染进程之间进行通信的机制,建立了双向的通信管道
- Message Channel 通过
MessageChannel对象来创建,其中包括两个相关的MessagePort对象:port1和port2。- port1和port2这两个端口对象可以在不同的渲染进程之间进行传递和共享
- Message Channel 通过
- 可以在渲染进程之间通过发送和接收消息来进行交互
- 跨渲染进程的通信,可以使用
postMessage方法发送消息,并通过onmessage事件来监听接收到的消息
- 跨渲染进程的通信,可以使用
- 通过ipc方式,通过主进程去建立连接,在消息通道通过message、postMessage
消息通道应用场景
- 音频、视频
- 获取数据任务 -> 处理数据
- canvas渲染
- 获取到后台数据之后,通过canvans来绘制图片来下载
Electron通信方式
- ipc通信 【可以应对绝大多数场景】
- ipcRenderer.send 发送消息,然后使用 ipcMain.on 接收
- 渲染进程向主进程传递参数
- 在预加载脚本配合contextBridge,使用ipcRenderer.send发送消息,主进程通过ipcMain.on定义事件来接收参数
- 主进程通过window对象来调用预加载脚本暴露的方法,来传递参数预加载脚本,预加载脚本再发参数传递给主进程
- remote 【
remote模块在 Electron 12 废弃,并将在 Electron 14 被移除. 由@electronic/remote模块替代,不推荐使用】 - 消息通道 =>MessageChannel 【可以在渲染进程之间通信】
- 通过预加载脚本 配合 contextBridge 【contextBridge提供安全机制可以使主进程与渲染进程通信,可以控制哪些api暴露】
- 使用invoke/handle可以实现进程双向通信 【invoke理解为调用的意思, 调用主进程】
- ipcRenderer.invoke 与 ipcMain.handle
预加载脚本
注意,预加载脚本默认情况下,只提供了部分能使用electron的api、部分node模块
- 可以设置sandbox为false、或者设置nodeIntegration为true, 就能使用electron和node其他模块了
由于Electron主进程可以完全操作系统的权限,为了避免渲染进程 直接调用主进程的方法 带来的安全问题,因此有了预加载脚本
- 预加载脚本可以理解为桥梁,是主进程和渲染进程的之间访问桥梁
- 通过预加载脚本,去访问主进程,把渲染页面的参数结果传递给渲染进程,在进行渲染页面
- 虽然在预加载脚本可以访问DOM, 可以进行操作DOM, 渲染页面,但是不建议
- 各司其职,操作DOM和渲染页面的操作,放在渲染进程去处理
- 虽然在预加载脚本可以访问DOM, 可以进行操作DOM, 渲染页面,但是不建议
- 避免在渲染进程 直接使用nodejs模块和electron模块可能带来的安全风险
- 预加载脚本提供了一种在渲染进程中安全地访问 Node.js 模块和 Electron API 的机制
预加载脚本何时注入?
- 预加载脚本在渲染进程加载网页之前注入
使用场景
- 提供全局变量或函数:预加载脚本可以在渲染进程中提供一些全局变量或函数,供你的应用程序中的所有渲染进程共享使用
- 访问底层系统功能:预加载脚本可以使用 Node.js 模块和 Electron API 来访问底层系统功能,比如读取文件、执行 Shell 命令、操作系统原生通知等
- 加强安全性:通过预加载脚本,你可以将某些敏感的 Electron API 功能封装在主进程中,并只将必要的功能暴露给渲染进程
- 主进程和渲染进程通信,配合contextBridge
使用
- 主进程中在webPreferences中的preload属性
webPreferences: {
preload: path.join(__dirname, 'preload.js')
}
- preload.js
const fs = require('fs');
// 访问node模块
const content = fs.readFileSync('package.json', 'utf-8');
console.log('content', content);
// 不建议DOM操作在预加载脚本处理,此代码最好放在渲染进程中处理DOM相关,DOM相关放在渲染进程中 【应各司其职】
window.addEventListener('DOMContentLoaded', () => {
console.log('DOM加载完');
// 可访问dom, 一般在渲染进程中访问dom,不建议在预加载脚本访问
});
沙箱模式
默认情况下,electron开启了沙箱模式,为了增强安全性,减少额外代码的风险
- 沙箱模式的目的:沙箱模式可以隔离渲染进程,使其不能直接访问底层操作系统或 Node.js 模块。这有助于防止潜在的安全漏洞
- 限制:在沙箱模式下,渲染进程/预加载脚本中 无法访问大多数 Electron模块和Node.js 模块
如何控制沙箱模式
- 通过窗口对象的 sandbox和nodeIntegration都可以设置
const win = new BrowserWindow({
webPreferences: {
nodeIntegration: true, // 控制是否使用node模块
// contextIsolation: false,
// sandbox:false, 控制是否沙箱模式
},
});
任务栏中是否显示窗口 dock状态栏
Dock 是 macOS 操作系统的功能,类似于 Windows 操作系统的任务栏或者 Linux 操作系统的面板。在 macOS 上,Dock 通常位于桌面底部/或者侧边,包含应用程序图标、文件夹图标、常用应用的快速启动图标等
- 窗口对象
BrowserWindow设置skipTaskbar属性
const win = new BrowserWindow({
skipTaskbar: true, // 任务栏中显示窗口
})
- 在mac系统中,隐藏dock状态栏
// 隐藏 dock 中的图标 【针对macOS】
app.dock.hide()
桌面应用通知
Notification模块
- 可以允许使用自定义模板、图像和其他灵活的元素进行高级通知
安装程序图标
mac
- 苹果系统的软件图标可以使用 png 或 icns
icns
icns图标是一种用于苹果 macOS 操作系统的图标文件格式。它是"图标套件"(Iconset)的一部分
window
- window 系统支持 png 与 icon 图片文件
核心概念
主进程和渲染进程
主进程在node环境、渲染进程在浏览器环境
- 因此在渲染进程可以操作DOM, 主进程无法操作DOM
主进程
Electron 运行 package.json 的 main 脚本的进程被称为主进程
- 启动项目时运行的main.js脚本就是主进程,在主进程的脚本可以创建web页面的形式GUI, 主进程只有一个
GUI :图形用户界面 (Graphical user interface)
主进程职责
- 创建渲染进程(可多个)
- 控制了应用生命周期(启动、退出APP以及对APP做⼀些事件监听)
- 调用系统底层功能、
- 调用原生资源
- 可调用的api 【Node.js API 、 Electron提供的主进程API(包括⼀些系统功能和Electron附加功能)】
渲染进程
- 每个页面都会运行自己的进程,这个进程就是渲染进程
渲染进程职责
- 用HTML和CSS渲染界面
- 用JavaScript做⼀些界面
- 可调用的api 【DOM API、NodeJS API、Electron提供的渲染进程API】
主进程和渲染进程通信
通过ipcMain、ipcRenderer模块来实现通信 【原理:事件订阅】
- 通过IPC通信
- IPC是基于事件传递
Inter-Process Communication(IPC,进程间通信)来实现主进程和渲染进程之间的通信,以及在主进程中的不同模块之间的通信。