主进程:这是应用程序的主控制中心,运行Node.js环境,负责管理和控制所有渲染进程和窗口。渲染进程:每个Electron窗口对应一个独立的渲染进程。它们运行在Chromium 渲染引擎中,负责显示用户界面。主窗口:主窗口是应用程序的主界面,通常是用于显示网页内容的Chromium 窗口。系统托盘图标(Tray):允许在桌面右下角显示小图标,以提供快速访问和与应用程序交互。开发流程
使用HTML、CSS 和JavaScript 创建用户界面。在主流程中使用Node.js进行应用逻辑控制。通过与底层操作系统API交互,实现文件操作、网络通信等功能。使用Electron 打包工具将您的应用程序打包为特定于平台的可执行文件。核心架构图
Electron安装
安装electron
首先,我们需要在常规React 项目中安装Electron。为了让我们的功能代码部分和Electron窗口部分更加清晰,我们可以在项目根目录下新建一个desktop文件夹,专门用于存放一些Electron代码和资源。目录结构大致如图:
App生命周期
应用运行
使用npm run prod-electron 命令启动生产环境。生产环境是指用webpack封装渲染层的功能代码,以便渲染到窗口中。真正的生产环境应该是使用Electron-Builder 打包的应用程序,如下所述。此时,process.env.NODE_ENV 未定义。
Electron应用打包
appId:指定应用程序的唯一标识符。该值将在打包和部署期间使用。 files:指定要打包的文件。 directories.output:指定输出目录的路径,即构建的文件将保存在dist目录中。 nsis:指定NSIS(Nullsoft Scriptable Install System)打包的相关配置。 oneClick:是否启用一键安装模式。 allowedElevation:是否允许提升安装权限。 allowedToChangeInstallationDirectory:是否允许用户更改安装目录。 installerIcon:安装程序的图标文件路径。 uninstallerIcon:卸载程序的图标文件路径。 installerHeaderIcon:安装程序的标头图标文件路径。 createDesktopShortcut:是否在桌面上创建快捷方式。 createStartMenuShortcut:是否在开始菜单中创建快捷方式。快捷方式名称:创建的快捷方式的名称。 win:指定Windows平台的配置。 icon:指定应用程序的图标文件路径。 artifactName:定义生成的构建文件的命名规则模板。 target:指定构建的目标平台,这里是NSIS。 electroDist:指定预先下载的Electron包的路径。特别注意有几点需要特别注意:
首先,我们使用的logo.ico文件大小至少为256*256。由于我们在打包时需要用到Electron相关的包文件,为了提高打包速度,我们通常会提前下载与我们的node_modules相同版本的.zip包,然后进行打包。使用ElectronDist 指定打包的文件目录可以减少打包时间。自定义artifactName,这是我们打包后可以安装的.exe可执行文件的名称。 electro-builder的打包原理其实就是将package.json同目录下的所有文件打包。进行整体打包输出,如下图所示。 package.json同目录下有一些文件夹我们不需要打包。其中,dist是我们上次打包输出的内容,Electron是我们预先下载的打包文件。需要的.zip包,下面的node_modules是我们开发时使用的依赖包,这些不需要打包。因此,我们在打包的时候需要指定我们需要打包的文件夹。这时候我们就需要用到package.json中构建配置中的files属性了。按照上面的配置,我们只需要打包build目录下的文件和main下的文件即可。能。这里的build目录是渲染层的代码,main下面是我们主进程代码的打包内容。
dist目录包含打包的内容。第一个红框中的Harbor.exe是直接可执行文件,不需要安装。第二个红框中的.exe可执行文件是可安装文件。在文件夹中双击进入安装过程。
Electron常用API详解
使用BrowserWindow创建窗口
创建窗口常用配置Option
当我们创建窗口时,我们可以配置许多自定义配置。以下是一些常见的配置和分析:
width 和height:用于设置窗口的初始宽度和高度。 x 和y:根据屏幕坐标控制窗口的初始位置。 fullscreen:布尔值,指定窗口是否以全屏模式启动。 ressized:布尔值,控制用户是否可以调整窗口大小。 minWidth 和minHeight:指定窗口的最小宽度和最小高度。 maxWidth 和maxHeight:指定窗口的最大宽度和最大高度。 frame:布尔值,指定是否显示窗口的外框(包括标题栏和控制按钮)。 title:用于设置窗口的标题。 icon:指定窗口的图标文件路径。 backgroundColor:用于设置窗口的背景颜色。 webPreferences:用于配置窗口的Web集成选项,例如启用Node.js、预加载脚本等。 nodeIntegration:指定是否在渲染过程中启用Node.js集成,允许在渲染中使用Node.js API过程。 contextIsolation:启用上下文隔离,将渲染进程的环境与主进程隔离,提高安全性。 preload:指定在渲染进程运行之前加载的预加载JavaScript 文件的路径。 devTools:指定是否允许在窗口中打开开发者工具。 webSecurity:指定是否启用同源策略,限制对其他来源的页面请求。 alwaysOnTop:布尔值,控制窗口是否始终保持在顶部。 fullscreenable:布尔值,指定窗口是否可以进入全屏模式。 show:布尔值,指定窗口创建后是否立即显示。透明:布尔值,指定窗口是否支持透明度。 Parent and modal:用于实现模态窗口的行为。 closeable:布尔值,指定用户是否可以关闭窗口。 focusable:布尔值,指定窗口是否可以聚焦。最小化和最大化:控制窗口是否可以最小化和最大化。窗口本身有很多实例属性,它们可以让我们获取窗口当前的一些状态。以下是一些常用的实例属性。
win.id - 窗口的唯一ID。 win.webContents - 包含窗口Web 内容的BrowserWindowProxy 对象。 win.devToolsWebContents - 开发人员工具窗口的webContents。 win.minimized - 是否允许最小化窗口,默认为true。 win.maximized - 是否允许窗口最大化,默认为true。 win.fullScreenable - 是否允许全屏窗口,默认为true。 win.resizing - 是否允许改变窗口大小,默认为true。 win.closesable - 是否允许窗口关闭,默认为true。 win.movable - 是否允许移动窗口,默认为true。 win.alwaysOnTop - 是否始终保持在最前面,默认为false。 win.modal - 是否为模态窗口,默认为false。 win.title - 窗口标题。 win.defaultWidth/Height - 窗口的默认宽度和高度。 win.width/height - 窗口的当前宽度和高度。 win.x/y- 窗口左上角的坐标。
窗口常用的实例方法
win.loadURL(url)-将指定的URL加载到窗口中,通常用于加载本地文件或远程网页。 win.webContents.send(channel,args) - 在窗口之间发送异步消息。 Channel 是标识消息类型的字符串,args 是要传递的参数。 win.show() - 显示窗口,通常与hide() 方法结合使用。 win.hide() - 隐藏窗口。 win.close()- 关闭窗口win.minimize()- 最小化窗口win.maximize()- 最大化窗口win.restore()- 恢复窗口大小和位置。 win.setSize(width, height[, animate])- 设置窗口的宽度和高度。 win.setPosition(x, y[, animate]) - 设置窗口的位置。 win.getTitle() - 获取窗口的标题。 win.setTitle(title)- 设置窗口的标题。 win.setMenu(menu) - 设置窗口的菜单。 win.setResizable(resizing) - 设置窗口是否可以调整大小。 win.setAlwaysOnTop(flag[, level[,relativeLevel]])- 将窗口置于顶部。 win.setMenu(null) - 隐藏窗口的菜单栏。 win.setProgressBar(progress) - 设置窗口的任务栏进度条。 win.focus() - 将窗口置于前台并获得焦点。 win.isVisible() - 返回窗口是否可见。 win.isFullScreen() - 返回窗口是否全屏。 win.isMaximized() - 返回窗口是否最大化。 win.webContents.executeJavaScript(code[, userGesture]) - 在窗口的渲染过程中执行一段JavaScript 代码。 win.openDevTools([options])- 打开开发者工具。
创建右下角托盘
Menu.buildFromTemplate是Electron的一个方法,用于创建菜单。菜单的标签就是显示的内容。 click是点击后触发的事件。托盘.setToolTip('Harbour') 用于设置鼠标悬停时的显示。提示消息托盘.setContextMenu(contextMenu)将使用Menu.buildFromTemplate创建的菜单设置为托盘菜单托盘.on('click', ()={})托盘被点击时触发事件。这里我们设置mainWindowsshow 应用层与主进程的通信进程为:
应用层使用ipcRender.send 方法将事件和数据传递给主进程。主进程使用ipcMain.on 或ipcMain.once 方法来监听事件并获取数据。主进程使用ipcMain.removeListener 删除事件侦听器或ipcMain.removeAllListeners 删除所有事件侦听器。主流程使用窗口实例的webContents.send方法将事件和数据传递给应用层。应用层使用ipcRender.on或ipcRender.once来监听事件并获取数据。应用层使用ipcRenderer.removeListener 移除事件监听器或者ipcRenderer.removeAllListeners 移除所有事件监听图如下
将ipcRender,process注入到应用层
应用层封装注入的Api
应用层发送事件到主进程
对话框是Electron 提供的模块之一,用于在桌面应用程序中创建对话框以与用户交互。它可以用来打开文件、保存文件、显示警告、错误等信息,以及获取用户输入等操作。以下是一些常用的对话框模块方法
打开文件对话框
dialog.showOpenDialog([browserWindow, ]options) 打开一个文件选择对话框,允许用户选择一个或多个文件。
browserWindow(可选):对父窗口的引用。如果不传递该参数,对话框将成为模态窗口。 options:配置对象,可以包含以下属性: defaultPath:字符串,指定对话框的默认路径。 filters:数组,定义文件类型过滤器。 dialog.showSaveDialog([browserWindow, ]options) 打开文件保存对话框,允许用户选择要保存的路径和文件名。
browserWindow(可选):对父窗口的引用。 options:配置对象,可以包含以下属性: defaultPath:字符串,指定对话框的默认路径。 dialog.showMessageBox([browserWindow, ]options) 显示消息框,通常用于警告或通知用户。
browserWindow(可选):对父窗口的引用。 options:配置对象,可以包含以下属性: type:可以是'none'、'info'、'error'、'question'、'warning',决定消息框的类型。 title:字符串,消息框的标题。 message:字符串,要显示的消息文本。 Buttons:包含消息框按钮的数组,例如['是','否','取消']。 dialog.showErrorBox(title, content) 显示错误框以显示错误信息。
title:字符串,对话框标题。 globalShortcut 是Electron 提供的用于注册和响应全局键盘快捷键的模块之一。这允许您在Electron 应用程序中创建全局快捷键来执行特定操作或触发事件。下面是一些常用的globalShortcut 模块方法globalShortcut.register(accelerator, callback) 来注册全局快捷键。
Accelerator:字符串,表示要注册的快捷键,如'CmdOrCtrl+X'。 Menu 是Electron 中用于创建和管理应用程序菜单的模块。它允许您在应用程序的菜单栏、上下文菜单等中定义菜单项,以便用户可以通过单击菜单项来执行特定操作。下面是一些常用的Menu模块方法和属性
Menu.buildFromTemplate(template) 从模板数组创建菜单。 template:包含菜单项的数组。每个菜单项都是一个对象,包括标签、点击等属性。 Menu.setApplicationMenu(menu) 设置应用程序菜单,通常用于顶级菜单栏。 menu:要设置为应用程序菜单的菜单对象。
菜单属性项
label:字符串,菜单项显示的文本。 Accelerator:字符串,可以是组合键,例如“CmdOrCtrl+X”。 click:函数,点击菜单项时执行的回调函数。角色:内置角色,例如“复制”、“粘贴”,将触发预定义的操作。 menu.append(menuItem) 将菜单项附加到菜单末尾。 menu.insert(position, menuItem) 在指定位置插入菜单项。 menu.getMenuItemById(id) 根据菜单项的id 获取菜单项。 menu.popup([options]) 在指定位置弹出菜单。 options:可以包含x和y属性的对象,表示弹出菜单的位置。
使用nativeImage 处理图像
nativeImage是Electron提供的用于处理图像的模块之一。它可以加载图像文件、从屏幕捕获图像、创建空白图像等等。 nativeImage支持跨平台,可以在主进程和渲染进程中使用。
从文件路径创建图像对象。 path:字符串,图像文件的路径。从缓冲区创建一个图像对象。 buffer:包含图像数据的Buffer对象。从系统的命名图像创建图像对象。 imageName:包含系统命名图像的字符串,例如“NSStopProgressTemplate”。从文件路径创建缩略图。 path:字符串,图像文件的路径。 size:包含宽度和高度属性的对象,指定缩略图的宽度和高度。检查图像是否是macOS 模板图像。将图像转换为数据URL。 screen是Electron提供的模块之一,用于获取屏幕和显示的信息,并执行屏幕相关的操作。以下是一些常用的屏幕模块方法和属性:
用户评论
这篇文章太棒了!看完之后我已经对利用 Electron 和 React 开发桌面应用有了更深刻的理解。10000 多字确实很多,但因为内容都很详尽,一点也不水。 作为前端开发者,学习 Electron 可以开辟一个全新的领域,以后可以开发一些有创意的工具或软件,想想都觉得激动!
有10位网友表示赞同!
标题有点唬人,我以为会讲到非常先进的桌面开发技术,结果还是比较基础的 React 开发套在 Electron 上面。不过文章写得的确详细,对入门Electron 的同学还是很有帮助的。
有11位网友表示赞同!
终于找到一篇将 Electron 和 React 结合用的教程了!很久以来我一直想尝试一下把前端项目迁移到桌面端,这篇教程正好点醒了我的想法。我准备花时间好好研究一下,相信以后能做出一些有趣的桌面应用!
有10位网友表示赞同!
10000 多字真的太长了,我就只 skimmed 一下 key points; Electron 和 React 的结合确实很强大,但我觉得这两种技术在桌面应用中还是有一些局限性。毕竟桌面应用需要考虑到更加复杂的用户体验和系统资源管理等等问题。
有17位网友表示赞同!
作为一名资深前端开发者,我早就已经掌握了 Electron 和 React 的基础知识,这篇教程的内容对我来说比较生僻。不过对于初学者来说,这篇文章应该可以帮助他们快速入门!
有17位网友表示赞同!
说实话,Electron 开发桌面应用确实存在一些性能问题,尤其是复杂项目的开发效率会比较低下。还有就是跨平台兼容性也需要仔细考虑。尽管如此,Electron 仍旧是一种值得学习的工具,它为前端开发者提供了拓展到桌面端的机会。
有9位网友表示赞同!
看到这么多字数,我差点被吓跑!不过仔细看了文章后发现内容的确非常全面实用,特别是关于 Electron 和 React 的结合方法讲解的非常详细。建议作者可以把文末的一些代码片段放到独立的 GitHub 库里面以便于大家查看学习,同时也可以加入一些实战案例,对读者理解更易加深。
有6位网友表示赞同!
Electron 开发确实是越来越火了,因为它能够将网页技术转移到桌面端,开发起来相对简单快捷。 这篇教程非常棒,帮我入门了 Electron 和 React 的组合运用,以后可以尝试开发一些小的工具应用!
有16位网友表示赞同!
我有个想法,能不能用 Electron 和 React 开发一款开源的笔记软件?功能上类似于 Notion ,方便 myself 记录工作和学习内容。
有7位网友表示赞同!
Electron 确实是一款神奇的工具!通过它,前端开发者可以将网站转化成桌面应用,打开了一个新的世界。这篇文章非常详细,对初学者来说简直是宝典啊!
有20位网友表示赞同!
我有一款网页游戏想移植到桌面端,感觉 Electron 和 React 可以完美结合完成这个任务。 希望能尽快学习完这篇教程,实现我的梦想!
有6位网友表示赞同!
Electron 的跨平台兼容性还有待提高,特别是某些操作系统的系统资源管理机制不太完善,这会导致开发过程遇到一些瓶颈。不过随着技术的进步,我相信 Electron 会在桌面应用领域发挥更大的作用。
有14位网友表示赞同!
前端的知识体系一直在扩展,现在就连桌面应用开发也开始成为主流趋势了! 这篇文章让我对 Electron/ React 组合感到兴奋,我迫切希望把它应用到我的项目中,创造出一些突破性的应用!
有12位网友表示赞同!
这篇教程写的很棒!终于有个地方可以帮我理解 Electron 和 React 的结合运用。 我一直在想学习跨平台开发技术,这篇文章给了我很大启发!
有5位网友表示赞同!
Electron 开发桌面应用确实是一个很好的选择,它能够帮助前端开发者快速搭建可用的桌面应用程序,并且可以使用 JavaScript、HTML和 CSS 等熟悉的语言进行开发。 这篇文章内容很棒,将 Electron 和 React 整合起来非常实用。
有9位网友表示赞同!
学习 Electron 和 React 来开发桌面应用听起来很有潜力!但对于我目前的工作来说可能不太合适,因为我的项目主要集中在移动端开发上。或许将来有机会再深入探索这个领域!
有13位网友表示赞同!
虽然这篇文章写的很详细,但我不太好理解一些关于 Electron 核心逻辑的部分,也许需要更加深入的学习才能真正掌握这些知识点。
有10位网友表示赞同!
Electron 和 React 的组合确实非常强大,它让前端开发人员可以轻松地将网页技术应用于桌面端,不再局限于浏览器! 我计划花时间学习这篇教程,并创作一个自己的桌面应用来锻炼自己!
有5位网友表示赞同!