探索 Electron:将 Web 技术带入桌面应用

news2024/11/23 15:22:51

Electron是一个开源的桌面应用程序开发框架,它允许开发者使用Web技术(如 HTML、CSS 和 JavaScript)构建跨平台的桌面应用程序,它的出现极大地简化了桌面应用程序的开发流程,让更多的开发者能够利用已有的 Web 开发技能来构建功能强大且跨平台的应用程序,这对于提升开发效率和应用程序的快速交付具有重要意义。

目录

初识Electron

项目工程搭建

加载本地文件

完善窗口行为

配置自动重启

主进程与渲染进程

进程通信

打包应用


初识Electron

Electron是一个由GitHub及众多贡献者组成的活跃社区共同维护的开源项目,其兼容Mac、Windows和Linux,可以构建出三个平台的应用程序,这里给出其 官网 和 中文网 ,如下:

像我们平常耳熟能详的vscode就是使用electron来进行开发的,当然还要一些我们常用的工具都是采用electron进行开发,包括我们目前使用的最新版的腾讯QQ,也是采用了electron框架技术实现多端跨平台运行,可以说electron算是一个生态完善、功能齐全、系统简便的框架了。

对于创建常见的桌面GUI工具有以下各种框架,这里简单说一下各种框架之间的优缺点:

名称语言优点缺点
QTC++跨平台、性能好、生态好依赖多,程序包大
PyQTPython底层集成度高、易上手授权问题
WPFC#类库丰富、扩展灵活只支持Windows,程序包大
WinFormC#性能好、组件丰富、易上手只支持windows,UI差
SwingJava基于AWT,组件丰富性能差,UI一般
NW.jsJS跨平台性好,界面美观底层交互差、性能差,包大
ElectronJS相比NW发展更好底层交互差、性能差,包大
CEFC++性能好,灵活集成,UI美观占用资源多,包大

技术是为业务服务的,选择合适的最重要,如下对框架进行一个概述:

1)底层依赖+调用:CEF、QT、Swing

2)UI美观:Electron(NW.js)、PyQT

3)跨平台:Swing(JAVA)、PyQT(Python、C++)、Electron(前端)

Electron技术架构:Electron的核心组成主要有以下三个部分组成,这里对这三个部分进行简述:

Chromium:渲染引擎,负责显示HTML、CSS和JS内容,提供了现代浏览器的功能

Node.js:后端引擎,提供访问本地文件系统和操作系统功能的能力

Native apis:操作系统或平台提供的原生应用程序接口(API)用于与硬件和系统功能进行交互

Electron说明:它其实就是一个实时的框架,将chromium和node.js整合一个运行环境当中,它允许我们使用web技术来构建桌面应用程序,并可以调用一些api来对不同操作环境下的系统进行相应操作,最终实现一个跨平台并且兼容性极好的桌面应用。

Electron工作流程:Electron开发桌面端应用是如何完成整体的工作呢?这里做一个简单的概述,从下图所示可以看出,桌面应用其实就是运行在不同操作系统上的一款软件,当前我们要讨论的就是在底层系统运行上层发生的一些行为:

具体流程包括初始化项目、创建基本文件结构、编写主进程脚本和前端页面、配置package.json以及启动和调试应用,主进程可以看做是 package.json 中 main 属性对应的文件,一个应用只会有一个主进程,只有主进程可以进行GUI的API操作;渲染进程中Windows展示的界面通过渲染进程表现,一个应用可以有多个渲染进程:

项目工程搭建

接下来我们开始搭建electron项目了,首先我们先打开electron官网,对于新手来说直接阅读官网是一个比较不错的选择,这里我们点击官网的快速入门,往下滑动找到我们想要的信息。

第一步:首先我们先查阅一下自身电脑有无安装node环境,没有的话请参考我之前的文章进行安装:地址 ,安装最新稳定版本的node即可:

第二步:通过 npm init 命令去初始化包,这里就不先直接上框架讲解了,下一篇文章在说,初始化包命令直接一路回车即可:

第三步:接下来我们就需要开始安装electron相关包了,命令如下,安装完成之后配置一下start:

npm install --save-dev electron

第四步:在根目录创建main.js文件用作electron的入口文件,然后编写相应的基础代码,如下:

// app应用;BrowserWindow 窗口
const { app, BrowserWindow } = require('electron')

// 当app准备完毕,创建窗口
app.on('ready', () => {
    new BrowserWindow({ // 窗口的配置
        width: 800,
        height: 600
    })
})

接下来直接终端执行 npm start 命令,直接运行项目,如下可以看到桌面应用已经启动了,其自带一些桌面的菜单和相关基础按钮:

这里我们可以将自带的导航栏隐藏掉,并且在空白页面中内嵌一个别的网站的网页,如下:

// app应用;BrowserWindow 窗口
const { app, BrowserWindow } = require('electron')

// 当app准备完毕,创建窗口
app.on('ready', () => {
    const win = new BrowserWindow({ // 窗口的配置
        width: 800,
        height: 600,
        autoHideMenuBar: true, // 自动隐藏菜单栏
    })
    win.loadURL('http://www.baidu.com') // 加载页面
})

呈现的效果如下所示:

当然关于窗口的配置还有许多相关的配置项,大家可以自信去官网了解,这里就不再一一介绍了,后面讲解项目遇到相应问题需要解决的时候,再讲解相关的配置:

加载本地文件

上文我们讲解到了使用electron运行项目以及使用了一个线上的链接进行项目的实现,接下来我们开始编写如何在electron中加载本地文件,首先我们先创建一下src文件,新建一个html和css文件,然后在文件中编写相应的内容,如下:

然后我们调用BrowserWindow中的函数加载本地文件,如下所示:

// app应用;BrowserWindow 窗口
const { app, BrowserWindow } = require('electron')

// 当app准备完毕,创建窗口
app.on('ready', () => {
    const win = new BrowserWindow({ // 窗口的配置
        width: 800,
        height: 600,
        autoHideMenuBar: true, // 自动隐藏菜单栏
    })
    win.loadFile('./src/index.html') // 加载页面
})

最终呈现的效果如下所示,可以看到本地的文件已经在桌面端中加载出来了:

如果想像浏览器那样使用控制台的话,可以通过快捷键 ctrl + shift + i 打开控制台,如下所示,如果想刷新页面内容的话和浏览器一样,也是f5即可:

因为vscode也是通过electron开发的嘛,所以说vscode也是有控制台的,如下这个就是vscode的控制台:

然后我们打开控制台,一开始会报出如下的警告,说是内容安全策略的问题,这里我们在hmtl文件加上如下代码即可消除警告:

<meta http-equiv="Content-Security-Policy" content="default-src 'self'; img-src https://*; child-src 'none';" />

完善窗口行为

在window系统下我们开启一个应用,关闭之后是直接在任务栏中消失掉了,而mac系统还是会在任务栏中保留的,为了匹配不同系统下的使用习惯,这里我们也要对electron进行相应的代码配置,如下:

// app应用;BrowserWindow 窗口
const { app, BrowserWindow } = require('electron')

const createWindow = () => {
    const win = new BrowserWindow({ // 窗口的配置
        width: 800,
        height: 600,
        autoHideMenuBar: true, // 自动隐藏菜单栏
    })
    win.loadFile('./src/index.html') // 加载页面
}

// 当app准备完毕,创建窗口
app.on('ready', () => {
    createWindow()
})

// 当所有的窗口都被关闭时,并且还不是苹果系统,则直接退出程序
app.on('window-all-closed', () => {
    if (process.platform !== 'darwin') app.quit()
})

// 当应用被激活时,判断当前窗口的数量,如果是0就创建窗口
app.on('activate', () => {
    if (BrowserWindow.getAllWindows().length === 0) createWindow()
})

配置自动重启

我们每次对代码进行修改都需要手动去重启electron应用才可以看到新的效果,这对编写代码的效率来讲是很底下的,所以这里我们需要配置一下自动重启的配置,终端执行如下命令:

npm i nodemon -D

然后我们在package.json文件中配置一下启动命令如下:

"scripts": {
  "start": "nodemon --exec electron ."
}

当我们在main.js文件中打印一下可以看到会被实时监听到:

但是我们修改本地文件,页面是不会发生变化的,每次还需要我们手动去ctrl + r 强制刷新一下才行

这对于开发者来说还是不太友好,所以这里我们需要一下nodemon.json规则才行,如下我们在根目录创建 nodemon.json 文件,内容如下:

{
    "ignore": [
        "node_modules",
        "dist"
    ],
    "restartable": "r",
    "watch": ["*.*"],
    "ext": "html,js,css"
}

接下来当我们开始编写本地文件的时候,会自动重启electron桌面项目进行实时刷新:

主进程与渲染进程

在Electron中,主进程(Main Process)和渲染进程(Renderer Process)是两个核心概念,它们在应用程序中扮演着不同的角色和功能:

主进程(Main Process):主进程是整个 Electron应用程序的核心,负责管理应用的生命周期和主要的系统交互,通常一个Electron应用程序只有一个主进程,负责创建应用窗口(BrowserWindow),处理系统事件(如文件系统访问、进程间通信等),以及执行与操作系统交互的主要任务。

渲染进程(Renderer Process):渲染进程是Electron应用程序中负责展示界面和与用户交互的部分,每个应用窗口都运行在单独的渲染进程中,渲染进程通过Web页面(通常是用 HTML、CSS 和 JavaScript 编写的)来实现应用的用户界面。

如下通过一个简单的代码进行示例:

如果想在js文件中调用一些node.js身上的内容是直接报错的,这里我们需要借助预加载脚本来作为主进程与渲染进程之间的桥梁,如下我们在根目录下创建预加载脚本preload.js,然后在主进程中进行相应的代码配置:

electron的执行顺序就是 主进程 -> 预加载脚本 -> 渲染进程,这里我们做一个简单的样式:

最终打印的效果如下所示:

预加载脚本不像渲染进程无法时候node中的api,其是可以使用一些node环境中的api进行操作的,如下我们在预加载脚本中使用electron构建桥梁,然后把当前的node版本暴露出去,在渲染进程中是可以直接拿到的:

演示效果如下:

进程通信

渲染进程流向主进程(单向):

最终呈现的效果如下所示:

渲染进程与主进程互通(双向):接下来我们直接通过渲染进程去调用主进程的node中的API函数来获取系统中的数据,这里做一个简单的演示:

呈现的效果如下所示:

主进程流向渲染进程(单向):主进程向渲染进程发送数据是通过send和on方法,和上面讲述的第一个方法反过来即可,这里不再赘述。

打包应用

在我们编写完electron应用之后,接下来我们开始对这个应用进行打包,终端执行如下命令:

npm i electron-builder -D

安装完成之后,接下来我们需要对我们的package.json文件进行一定的配置,如下:

"scripts": {
  "start": "electron .",
  "build": "electron-builder"
}

然后在设置一下build打包命令的配置:

"build": {
  "appId": "com.xi",
  "win": {
    "icon": "./logo.png",
    "target": [
      {
        "target": "nsis",
        "arch": ["x64"]
      }
    ]
  },
  "nsis": {
    "oneClick": false,
    "perMachine": true,
    "allowToChangeInstallationDirectory": true
  }
},

效果如下所示:

然后我们终端执行 npm run build 命令进行打包,可以会遇到下面的一些报错,说我们一些依赖文件是缺失的,如下:

报错提示我们的缺失的安装包,我们就下载缺失的安装包,直接复制当前缺失的命令复制浏览器安装即可:

然后直接丢到对应的文件里面即可:

再次执行打包命令可以看到我们已经打包完成了:

回到我们的dist文件夹可以看到我们已经打包完成了:

然后我们双击安装包就可以和正常软件一样进行安装了,这里不再赘述:

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

微服务-网关Gateway

个人对于网关路由的理解&#xff1a; 网关就相当于是一个项目里面的保安&#xff0c;主要作用就是做一个限制项。&#xff08;zuul和gateway两个不同的网关&#xff09; 在路由中进行配置过滤器 过滤器工厂&#xff1a;对请求或响应进行加工 其中filters&#xff1a;过滤器配置…

Typescript 【实用教程】(2024最新版)含类型声明,类型断言,函数,接口,泛型等

简介 TypeScript 是 JavaScript 的超集&#xff0c;是 JavaScript&#xff08;弱类型语言&#xff09; 的强类型版本。 拥有类型机制文件后缀 .tsTypescript type ES6TypeScript 和 JavaScript 的关系类似 less 和 css 的关系TypeScript对 JavaScript 添加了一些扩展&#x…

《人人都是产品经理》:项目一图流

《人人都是产品经理》&#xff1a;项目一图流 项目一图流 项目一图流

[NSSCTF]-Reverse:[SWPUCTF 2021 新生赛]easyapp(安卓逆向,异或)

无壳 把后缀名改为zip&#xff0c;找到apk 查看jadx 这里调用了MainActivity的lambda$onCreate$0$MainActivity&#xff0c;然后又调用了Encoder进行异或。 exp&#xff1a; result棿棢棢棲棥棷棊棐棁棚棨棨棵棢棌 key987654321 flag for i in range(len(result)):flagchr(…

深入 SSH:解锁本地转发、远程转发和动态转发的潜力

文章目录 前言一、解锁内部服务&#xff1a;SSH 本地转发1.1 什么是 SSH 本地转发1.2 本地转发应用场景 二、打开外部访问大门&#xff1a;SSH 远程转发2.1 什么是 SSH 远程转发2.2 远程转发应用场景 三、动态转发&#xff1a;SSH 让你拥有自己的 VPN3.1 什么是 SSH 动态转发3.…

【工程实践】大模型推理指定GPU

前言 使用大模型进行推理&#xff0c;一般是在docker容器中&#xff0c;记录推理过程中遇到的问题。 问题描述 在使用docker容器时&#xff0c;在docker run时&#xff0c;如果使用的是--gpus all&#xff0c;这样在进入容器之后&#xff0c;会使用全部的GPU&#xff0c;如下图…

【算法专题--链表】两数相加 -- 高频面试题(图文详解,小白一看就懂!!)

目录 一、前言 二、题目描述 三、解题方法 ⭐双指针 -- 模拟进位 (使用哨兵位头节点) &#x1f95d; 什么是哨兵位头节点&#xff1f; &#x1f347;思路解析 &#x1f34d;案例图解 四、总结与提炼 五、共勉 一、前言 两数相加 这道题&#xff0c;可以说是--…

如何将Hive表的分区字段插入PG表对应的时间戳字段?

文章目录 1、背景描述2、场景分析 1、背景描述 数据仓库的建设通常是为业务和决策服务的。在数仓开发的应用层阶段&#xff0c;BI可以直接从主题层/业务层取数&#xff0c;而前端需要根据具体的作图需求通过后端查询数据库 作图的指标需要根据主题层/业务层做查询计算&#xf…

基于C语言的Jacobi迭代和Gauss-Seidel迭代的方程组求解实现

文章目录 Jacobi迭代方法介绍Gauss-Seidel迭代方法介绍具体代码实现示例题目实现效果 Jacobi迭代方法介绍 Jacobi迭代法是一种简单的迭代求解方法&#xff0c;适用于严格对角占优矩阵。其基本思想是利用当前迭代步的已知解来更新下一个迭代步的解。在C语言实现中&#xff0c;我…

Textual Learning2 -- 使用时的小问题

1、出现的问题&#xff1a; 在vscode里面直接运行函数会显示报错&#xff1a; 我尝试在vscode中含textual库的环境下运行&#xff0c;但仍然报错 2、解决方案&#xff1a; 在命令行中运行&#xff1a; 首先按winR&#xff0c;输入cmd打开命令行 或在已经安装的conda环境&a…

【JVM-01】引言

【JVM-01】引言 1. 什么是JVM&#xff1f;2. JDK、JRE、JVM比较3.常用的JVM有那些4.学习路线 1. 什么是JVM&#xff1f; JVM即 Java Virtual Machine(Java虚拟机)&#xff0c;是Java程序运行的环境(Java 二进制字节码运行环境)。 好处&#xff1a; 一次编写&#xff0c;到处…

Java基础(五)——ArrayList

个人简介 &#x1f440;个人主页&#xff1a; 前端杂货铺 ⚡开源项目&#xff1a; rich-vue3 &#xff08;基于 Vue3 TS Pinia Element Plus Spring全家桶 MySQL&#xff09; &#x1f64b;‍♂️学习方向&#xff1a; 主攻前端方向&#xff0c;正逐渐往全干发展 &#x1…

构建现代医疗:互联网医院系统源码与电子处方小程序开发教学

本篇文章&#xff0c;笔者将探讨互联网医院系统的源码结构和电子处方小程序的开发&#xff0c;帮助读者更好地理解和掌握这些前沿技术。 一、互联网医院系统源码结构 互联网医院系统通常由多个模块组成&#xff0c;每个模块负责不同的功能。以下是一个典型的互联网医院系统的主…

高精密机械设备中滚珠导轨的表面处理工艺有哪些?

滚珠导轨是机床传动和定位的传动元件&#xff0c;其表面处理方式对机床性能和使用寿命起着决定性的作用&#xff0c;不同的表面处理方法可以提高导轨的耐磨性、抗腐蚀性和整体性能。那么&#xff0c;滚珠导轨的表面处理方式有哪几种呢&#xff1f; 1、磨削法&#xff1a;磨削技…

myCrayon个人博客项目基于springBoot+Vue全栈开发

目录 项目介绍 简介 项目架构 项目模块组成 数据库设计 项目展示 首页 用户登录与注册 个人信息模块 商城展示 博客模块 博客浏览 博客发布与编辑 博客搜索 社区模块 新闻模块 后台管理系统 部署方式 结语 项目介绍 简介 项目类似于CSDN&#xff0c;支持所…

MyBatis Plus条件构造器使用

1Wrapper&#xff1a; 条件构造抽象类&#xff0c;最顶端父类 1.1 AbstractWrapper&#xff1a; 用于查询条件封装&#xff0c;生成 sql 的 where 条件 1.2 QueryWrapper&#xff1a; Entity 对象封装操作类&#xff0c;不是用lambda语法 1.3 UpdateWrapper&#xff1a; Update…

AVL树模拟

1.概念 虽然二叉搜索树可以缩短查找的效率&#xff0c;但如果数据有序或者接近有序时二叉搜索树树将退化为单支树&#xff0c;查找元素相当于在顺序表中搜索元素&#xff0c;效率低下。AVL 树是具有一下性质的二叉搜索树&#xff1a; 1.它的左右子树都是AVL树 2.左右子…

[Go 微服务] Kratos 使用的简单总结

文章目录 1.Kratos 简介2.传输协议3.日志4.错误处理5.配置管理6.wire 1.Kratos 简介 Kratos并不绑定于特定的基础设施&#xff0c;不限定于某种注册中心&#xff0c;或数据库ORM等&#xff0c;所以您可以十分轻松地将任意库集成进项目里&#xff0c;与Kratos共同运作。 API -&…

《mysql篇》--查询(进阶)

目录 将查询结果作为插入数据 聚合查询 聚合函数 count sum group by子句 having 联合查询 笛卡尔积 多表查询 join..on实现多表查询 内连接 外连接 自连接 子查询 合并查询 将查询结果作为插入数据 Insert into 表2 select * from 表1//将表1的查询数据插入…

【UE 网络】专用服务器和多个客户端加入游戏会话的过程,以及GameMode、PlayerController、Pawn的创建流程

目录 0 引言1 多人游戏会话1.1 Why&#xff1f;为什么要有这个1.2 How&#xff1f;怎么使用&#xff1f; 2 加入游戏会话的流程总结 &#x1f64b;‍♂️ 作者&#xff1a;海码007&#x1f4dc; 专栏&#xff1a;UE虚幻引擎专栏&#x1f4a5; 标题&#xff1a;【UE 网络】在网络…