Electron

Electron是什么

electron可以使用前端技术开发桌面应用,跨平台性,开发一套应用,可以打包到三个平台。

electron结合Chromium(谷歌内核)和 Node.js 和Native Api

当使用 Electron 时,很重要的一点是要理解 Electron 不是一个 Web 浏览器。 它允许您使用熟悉的 Web 技术构建功能丰富的桌面应用程序

官网:简介 | Electron


Electron广泛应用

使用Electron框架开发的知名软件。

Visual Studio Code、GithubDesktop、Postman、DockerDesktop...


Electron进程模型

主进程(main.js)。运行在node环境

一个应用只会有一个主进程,负责应用的生命周期、展示原生窗口、执行特殊操作和管理渲染进程。

渲染进程(render.js ),运行在浏览器环境

一个应用可以有多个渲染进程,渲染器进程负责展示图形内容。


快速上手

环境安装

node环境(v20.13.1)、npm环境(10.5.2)

测试安装是否成功,按下【win+R】键,输入cmd,打开cmd窗口

输入:node -v // 显示node.js版本

​ npm -v // 显示npm版本

npm config set registry https://registry.npmmirror.com/
 npm i electron -D

main.js

main 文件是 Electron 应用的入口。 这个文件控制 主程序 (main process),它运行在 Node.js 环境里,负责控制您应用的生命周期、显示原生界面、执行特殊操作并管理渲染器进程 (renderer processes)

const { app, BrowserWindow, ipcMain, Notification, Menu } = require('electron/main')
const path = require('node:path')
const fs = require('fs')function writeFile(_, data) {fs.writeFileSync('D:/hello.txt', data)
}function readFile() {const res = fs.readFileSync('D:/hello.txt').toString();return res
}
const createWindow = () => {const win = new BrowserWindow({width: 1000,height: 800,icon: path.join(__dirname, 'favicon.ico'),title: '简单网页',webPreferences: {preload: path.join(__dirname, 'preload.js')}})ipcMain.on('file-save', writeFile)ipcMain.handle('file-read', readFile)//自定义菜单项let menuTemp = [{label: '文件',submenu: [{label: '打开文件',click() {console.log('打开一个具体的文件')}},{ label: '打开文件夹' },{label: '关于',role: 'about'}]},{ label: '编辑' }]//生成自定义菜单let menu = Menu.buildFromTemplate(menuTemp)Menu.setApplicationMenu(menu)win.loadFile('index.html')// 创建并显示通知const notification = new Notification({title: '主进程通知',body: '恭喜你,学会了求雨之术,风来~雨来~'}).show();// 确保在窗口创建后调用 openDevTools//win.webContents.on('did-finish-load', () => {//  win.webContents.openDevTools();//});// 定时发送时间给渲染进程(每1秒)setInterval(() => {if (win && !win.isDestroyed()) {win.webContents.send('main-time', new Date().toLocaleTimeString());}}, 1000);
}
app.whenReady().then(createWindow)

index.html

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta http-equiv="Content-Security-Policy" content="default-src 'self'; img-src https://*; child-src 'none';" />
</head><body><div id="time">当前时间:加载中...</div><div class="hint">注意:输入内容,可以保存到d:/hello.txt,点击读取,可以读取该文件内容</div><input id="input" type="text"><button id="btn2">向D盘输入hello.txt</button><br><br><hr><button id="btn3">读取D盘hello.txt</button><script type="text/javascript" src="./render.js"></script>
</body></html>

render.js

const timeElement = document.getElementById('time');
const btn2 = document.getElementById('btn2');
const btn3 = document.getElementById('btn3');
const input = document.getElementById('input');btn2.onclick = () => {myAPI.saveFile(input.value)
}btn3.onclick = async () => {let data = await myAPI.readFile()alert(data)
}// 监听主进程发送的时间消息
myAPI.onMainTime((time) => {timeElement.textContent = `当前时间:${time}`;
});

preload.js

preload.js执行时机:预加载脚本在渲染器加载网页之前注入

预加载脚本preload.js(中间人),它在渲染进程运行(浏览器环境),人家也能访问一部分的node api。

const { contextBridge, ipcRenderer } = require('electron')contextBridge.exposeInMainWorld('myAPI', {saveFile: (data) => {ipcRenderer.send('file-save', data)},readFile: () => {return ipcRenderer.invoke('file-read')},// 监听主进程发送的时间消息onMainTime: (callback) => {ipcRenderer.on('main-time', (event, time) => callback(time))}
})

ipc进程通信

remote模块

Electron 官方已经明确表示,remote 模块是一个遗留的 API,不建议在新项目中使用。 他们鼓励开发者迁移到 Context Bridge。

remote 模块安全风险: 正如之前提到的,remote 模块允许渲染进程直接访问主进程的几乎所有对象,这带来了严重的安全风险。 恶意代码可能会利用 remote 模块来执行任意代码,甚至控制整个应用程序。

替代方案: Context Bridge (结合 ipcRenderer 和 ipcMain) 提供了更安全、更可控的进程间通信方式。


[渲染进程]调用[主进程] 无返回

需求:比如在页面上向d盘的文件写内容

主进程 ipcMain.on,写在app.whenReady().then()中

ipcMain.on('file-save', writeFile)function writeFile(_, data) {fs.writeFileSync('D:/hello.txt', data)
}

ipcRender.send 通过预加载脚本暴露了一个单行的 saveFile函数。

const { contextBridge, ipcRenderer } = require('electron')contextBridge.exposeInMainWorld('myAPI', {saveFile: (data) => {ipcRenderer.send('file-save', data)}})

最后在渲染器进程,也就是HTML页面就可以使用暴露出来的saveFile方法了

const btn2 = document.getElementById('btn2');
const input = document.getElementById('input');btn2.onclick = ()=> {myAPI.saveFile(input.value)
}

[渲染进程]调用[主进程] 有返回

双向 IPC 的一个常见应用是从渲染器进程码调用代主进程模块并等待结果,更适合请求-响应模式

需求:在页面上读取d盘的文件内容,点击按钮弹出d盘hello.txt文件内容

主进程 ipcMain.handle,写在app.whenReady().then()中

ipcMain.handle('file-read', readFile)function readFile() {const res = fs.readFileSync('D:/hello.txt').toString();return res
}

ipcRender.invoke 通过预加载脚本暴露了一个单行的 readFile函数。

const { contextBridge, ipcRenderer } = require('electron')contextBridge.exposeInMainWorld('myAPI', {readFile: () => {return ipcRenderer.invoke('file-read')}})

最后在渲染器进程,也就是HTML页面就可以使用暴露出来的readFile方法了

const btn3 = document.getElementById('btn3');
btn3.onclick = async () => {let data = await myAPI.readFile()alert(data)
}

[主进程]调用[渲染进程]

需求:页面显示当前时间,每1秒更新一次,来自主进程定时推送

主进程:webContents.send  发送消息

    // 定时发送时间给渲染进程(每1秒)setInterval(() => {if (win && !win.isDestroyed()) {win.webContents.send('main-time', new Date().toLocaleTimeString());}}, 1000);

ipcRenderer.on 预加载脚本监听主进程消息,暴露出onMainTime函数给渲染进程

callback本质是渲染进程向预加载脚本“注册”的一个“数据接收器”,让预加载脚本能把主进程的数据“交给”渲染进程处理。

const { contextBridge, ipcRenderer } = require('electron')contextBridge.exposeInMainWorld('myAPI', {// 监听主进程发送的时间消息onMainTime: (callback) => {ipcRenderer.on('main-time', (event, time) => callback(time))}
})

渲染进程

渲染进程调用onMainTime时传递了一个callback

const timeElement = document.getElementById('time');//监听主进程发送的时间消息
myAPI.onMainTime((time) => {timeElement.textContent = `当前时间:${time}`;
});

打包应用

electron-builder

需要梯子

安装打包工具

npm install electron-builder -D

打包应用 electron-builder(做很多自定义的东西)

愉快执行:npm run build,安装包在dist目录,74MB,安装后包含node和chromiun

npm run build

electron-forge

安装打包工具

npm install --save-dev @electron-forge/cli
npx electron-forge import

执行打包

npm run make

执行成功后,默认输出目录为out/make,里面会生成平台对应的分发文件,例如:

  • Windowsout/make/squirrel.windows/x64/my-app-1.0.0 Setup.exe(安装包)、my-app-1.0.0-full.nupkg(更新包)。
  • macOSout/make/dmg/my-app-1.0.0.dmg(磁盘镜像)、out/make/zip/my-app-1.0.0.zip(压缩包)。
  • Linuxout/make/deb/x64/my-app_1.0.0_amd64.deb(Debian包)、out/make/rpm/x64/my-app-1.0.0-1.x86_64.rpm(RPM包)。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/diannao/87420.shtml
繁体地址,请注明出处:http://hk.pswp.cn/diannao/87420.shtml
英文地址,请注明出处:http://en.pswp.cn/diannao/87420.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Kafka 拦截器深度剖析:原理、配置与实践

引言 在构建高可用、可扩展的消息系统时&#xff0c;Kafka以其卓越的性能和稳定性成为众多企业的首选。而Kafka拦截器作为Kafka生态中强大且灵活的功能组件&#xff0c;能够在消息的生产和消费过程中实现自定义逻辑的注入&#xff0c;为消息处理流程带来极大的扩展性和可控性。…

Flutter 与原生技术(Objective-C/Swift,java)的关系

在 iOS 开发中&#xff0c;Flutter 与原生技术&#xff08;Objective-C/Swift&#xff09;的关系 一、技术定位与核心差异 Flutter 语言&#xff1a;使用Dart 语言开发&#xff0c;通过 AOT&#xff08;提前编译&#xff09;将代码转换为原生 ARM 指令&#xff0c;无需依赖 iOS…

最新期刊影响因子,基本包含全部期刊

原文链接&#xff1a;2024年期刊最新影响因子&#xff08;IF&#xff09; 2024年期刊最新影响因子&#xff08;IF&#xff09; BioinfoR生信筆記 &#xff0c;注于分享生物信息学相关知识和R语言绘图教程。

java 设计模式_行为型_14策略模式

14.策略模式 策略模式作为一种软件设计模式&#xff0c;指对象有某个行为&#xff0c;但是在不同的场景中&#xff0c;该行为有不同的实现算法。 策略模式把这些算法&#xff0c;都抽取出来&#xff0c;组成一个一个的类&#xff0c;可以任意的替换&#xff0c;大大降低了代码…

【AI Study】第四天,Pandas(9)- 进阶主题

文章概要 本文详细介绍 Pandas 的进阶主题&#xff0c;包括&#xff1a; 自定义函数高级索引数据导出实际应用示例 自定义函数 函数应用 # 基本函数应用 def calculate_bonus(salary, performance):"""计算奖金Args:salary (float): 基本工资performance (…

Boost dlib opencv vs2022 C++ 源码安装集成配置

​在进行人脸检测开发时候出现 E1696: 无法打开源文件 "dlib/image_processing/frontal_face_detector.h 解决方案 1, 下载boost 需要:https://www.boost.org/ 或github git clone --recursive https://gitee.com/luozhonghua/boost.git 记住一定要完整版源码…

rest_framework permission_classes 无效的解决方法

写了一个特别简单的view&#xff1a; csrf_exempt login_required() authentication_classes([TokenAuthentication]) permission_classes([IsAdminUser, IsAuthenticated]) def department_management_view(request):if request.method POST:department_name request.POST.…

Windows 体系对比 + 嵌入式开发全流程拆解

一、操作系统层级对比&#xff1a;Windows 家族 vs Linux 家族 角色Windows 体系Linux 体系本质核心内核Windows NT KernelLinux Kernel操作系统引擎&#xff08;管理CPU/内存/硬件&#xff09;完整操作系统Windows 11 Home/ProUbuntu / Debian / CentOS内核 界面 软件 驱动…

C# 实现 gRPC高级通信框架简单实现

1. 前言 gRPC&#xff08;Google Remote Procedure Call&#xff09;是一个高性能、开源和通用的RPC框架&#xff0c;由Google主导开发。它支持多种编程语言&#xff0c;并广泛用于构建分布式应用程序和服务。gRPC基于HTTP/2协议&#xff0c;支持双向流、请求-响应和多请求-多…

将项目推到Github

前提条件 需要安装GIT需要注册GitHub账号 步骤 首先我们需要登录我们的GITHUB账号&#xff0c;然后点击新建存储库 然后起一个名字&#xff0c;设置一些私有公开即可 创建完成之后&#xff0c;这里有可以远程推送的命令 后面就直接输出命令即可 之后推送即可 git push orig…

K8S 专栏 —— namespace和Label篇

文章目录 namespace创建namespacenamespace使用默认namespaceLabel添加Label查询Labelnamespace 命名空间是一种用于在 kubernetes 集群中划分资源的虚拟化手段,每个资源都属于一个命名空间,使得多个团队或应用可以在同一个集群中独立运行,避免资源冲突。 创建namespace y…

44.第二阶段x64游戏实战-封包-分析掉落物列表id存放位置

免责声明&#xff1a;内容仅供学习参考&#xff0c;请合法利用知识&#xff0c;禁止进行违法犯罪活动&#xff01; 本次游戏没法给 内容参考于&#xff1a;微尘网络安全 上一个内容&#xff1a;43.第二阶段x64游戏实战-封包-代码实现获取包裹物品 之前的内容找到了掉落物的…

汇编语言期末快速过手笔记

一、计算机系统组成 计算机系统组成&#xff1a;由硬件系统和软件系统组成 硬件系统&#xff1a;CPU、存储器、输入/输出设备等物理部件软件系统&#xff1a;操作系统、各种语言、系统软件和应用软件 汇编语言分类 属于低级语言&#xff08;直接面向硬件&#xff09;与高级语言…

C++相比于C语言增加了哪些概念?

C相比于C语言增加了哪些概念&#xff1f; 作者将狼才鲸创建日期2025-06-17 CSDN阅读地址&#xff1a;C相比于C语言增加了哪些概念&#xff1f;Gitee源码目录&#xff1a;qemu/demo_代码示例/02_C_Class 目标受众&#xff1a;熟悉C语言&#xff0c;对C完全不了解&#xff0c;但…

HarmonyOS5 分布式测试:断网情况支付场景异常恢复验证

以下是针对HarmonyOS 5分布式事务在断网支付场景下的异常恢复验证全流程方案&#xff0c;综合关键技术与测试策略&#xff1a; 一、核心事务机制验证 ‌两阶段提交&#xff08;2PC&#xff09;协议‌ 模拟支付流程中网络中断&#xff0c;验证事务协调者能否正确处理预提交与回滚…

【狂飙AGI】第5课:前沿技术-文生图(系列1)

目录 &#xff08;一&#xff09;绘画本质&#xff08;二&#xff09;国内外AI转绘展&#xff08;三&#xff09;创作思路&#xff08;四&#xff09;美学理论&#xff08;1&#xff09;不可能美学&#xff08;2&#xff09;趋无限美学&#xff08;3&#xff09;反物理美学&…

发那科A06B-6290-H124 伺服驱动器

‌FANUC A06B-6290-H124 伺服驱动器核心性能解析‌ ‌一、核心控制能力‌ ‌多模式精密控制‌ 位置控制‌&#xff1a;支持高精度旋转角度/直线位移调节&#xff08;分辨率达脉冲级&#xff09;&#xff0c;适用于数控机床定位&#xff08;误差0.01mm级&#xff09;和机器人轨…

Spring Boot 项目启动优化

Spring Boot 项目启动优化是一个非常重要的话题&#xff0c;尤其是在微服务和云原生环境下&#xff0c;快速启动意味着更快的部署、更高效的弹性伸缩和更好的开发体验。 下面我将从分析诊断、优化策略和终极方案三个层面&#xff0c;为你提供一个全面、可操作的优化指南。 一、…

「爬取豆瓣Top250电影的中文名称」数据采集、网络爬虫

- 第 108 篇 - Date: 2025 - 06 - 16 Author: 郑龙浩&#xff08;仟墨&#xff09; 文章目录 **任务&#xff1a;爬取豆瓣Tap250电影的中文名称****代码****实现效果** 任务&#xff1a;爬取豆瓣Tap250电影的中文名称 代码 # 豆瓣前Tap 250 import requests from bs4 import…

MySQL 多表查询、事务

1.多表查询的分类 1.1 内连接 在 MySQL 中&#xff0c;内连接&#xff08;INNER JOIN&#xff09;返回的是两个表中满足连接条件的记录的交集。这个“交集”不是指整个表&#xff0c;而是指符合连接条件的行组合&#xff0c;也就是A表和B表中满足我们使用on指定条件的记录。图…