大家好,很高兴又见面了,我是web前端分享,由我带着大家一起关注前端前沿、深入前端底层技术,大家一起进步,也欢迎大家关注、点赞、收藏、转发!今天带着大家一起来聊聊Electron这个跨平台的桌面应用开发工具! 在开始学习Electron之前,你一定有这样的困惑:Electron是什么?Electron能做什么?许多伟大的公司使用Electron框架的原因又是什么? 带着这些问题和疑惑,通过本文的介绍,可助你全面地认识Electron这门新兴的技术,迅速找到其入门途径,并理解Electron为何被称为当下开发桌面App的最佳选择。初探Electron一、Electron是什么?(为何称之为跨平台桌面浏览器) 前端开发的魅力,在于开发者随时要面临全新技术的挑战! 曾几何时,作为前端开发者的你可曾想过:如何利用HTML、CSS和JavaScript构建跨平台的桌面应用程序?借助Electron,这项工作将比你想象的更加简单。 Electron作为一个使用新兴技术(包括JavaScript,HTML和CSS)创建桌面应用程序的框架,其负责处理硬件,开发者可以更专注于应用程序的核心并从底层更改其设计。 Electron设计之初便充分结合了当今最好的Web技术,作为一个跨平台的集成框架,它可以轻松地与Mac、Windows和Linux兼容。而所谓的集成框架也就是它将Chromium和Node。js很好的集成在了一起,并明确分工,Electron负责硬件部分,Chromium和Node。js负责界面与逻辑,大家井井有条,共同构成了一个成本低廉却十分高效的解决方案,在快速交付上甚至比Native还要快速。Electron发展里程碑2013年4月11日,Electron以AtomShell为名起步。2014年5月6日,Atom以及AtomShell以MIT许可证开源。2015年4月17日,AtomShell改名为Electron。2016年5月11日,1。0版本发布。2016年5月20日,允许向Mac应用商店提交软件包。2016年8月2日,支持Windows商店。 简而言之,ElectronJS是一个运行时框架,它允许用户使用HTML5、CSS和JavaScript创建桌面套件应用程序,而大部分应用程序都是由两种非常受欢迎的技术混合而成:Node。js和Chromium。因此,你编写的任何Web应用程序都可以在ElectronJS上正常运行。Electron的内置功能自动更新使应用程序能够自动更新、升级本机菜单和通知创建本机应用程序菜单和上下文菜单应用程序崩溃报告你可以将崩溃报告提交给远程服务器调试和分析Chromium的内容模块可以发现性能瓶颈和运行缓慢的原因。此外,你也可以在应用中使用自己喜欢的Chrome开发者工具Windows安装程序你可以快速而简单创建安装包二、Electron可以用来做什么?(哪些场景需要使用Electron) 以Windows平台应用开发为例,大部分人首先会想到使用成熟的开发方案,如QT(C)、WPF(C)等。但面临以下几种使用场景,这些方案将显得捉襟见肘:公司要设计一个全新的APP,但技术人员大部分由前端开发构成公司原本就有在线的Web应用,但是想让该应用能够在桌面端直接打开(离线状态下也可使用),并增加一些与系统交互的功能 以我的亲身经历为例: 在SpreadJS项目中,我们需要将基于web版的表格编辑器封装成APP使用,同时增加文件操作的能力,如导入导出excel、导入PDF等,而SpreadJS是一个纯前端的表格控件,开发人员全部由前端开发组成,对C和C并不熟悉,如果投入过大的时间精力用来学习,整个项目的技术管理和项目管理将变得无法控制。除此之外,鉴于项目本身对应用的业务逻辑要求并不高,只是套一个具有浏览器属性的运行环境即可,因此,单独为此配置C、C开发人员将无形中提升更多项目成本。 为此,我们引入了Electron框架:现有的前端开发人员能在不学习其他语言的情况下,直接搞定上述需求,这就是Electron为我们带来的价值。三、为什么选择Electron?(Electron的出现为前端开发者谋得了一份好差事) 可以这么说,Electron这个框架让网路里流传很广的一句话不再是玩笑:不要和老夫说什么C、Java,老夫行走江湖就一把JS,遇到需求撸起袖子就是干。Electron可以帮助前端开发者在不需要学习其他语言和技能的情况下,快速开发跨平台桌面应用。 Electron的出现将蚕食很大一部分桌面客户端领域的市场份额,鉴于它的跨平台特性,在不同系统之间仅需少量的优化工作。可想而知,这个成本到底有多低。 在开发的体验上,Electron是基于Chromium和Node。js的,所以几乎所有的Node。js模块都可以在Electron上运行。 使用npm搭积木的方式快速交付一个产品。 四、使用Electron框架的大型应用成功案例 1。SpreadJS纯前端表格控件 SpreadJS是一款基于HTML5的纯前端电子表格控件,兼容450种以上的Excel公式,可满足WebExcel组件开发、表格文档协同编辑、数据填报、Excel类报表设计等业务场景,从而降低企业研发成本和项目交付风险。 2。WebTorrent WebTorrent,作为第一个在浏览器中运行的torrent客户端,是一个完全由JavaScript编写并使用WebRTC进行点对点传输的客户端应用。无需任何插件,扩展或安装,WebTorrent将用户链接到分散的浏览器到浏览器网络,以确保有效的文件传输。 WebTorrent使用Electron框架开发,使其尽可能轻量、无广告且开源。此外,使用Electron还有助于流式传输,并充当混合客户端,将应用程序连接到所有流行BitTorrent和WebTorrent网络。 3。WordPress WordPress桌面是一个使用了Electron和React作为框架的桌面应用程序,提供无缝的跨平台体验,允许用户专注于他们的内容和设计,而不会被任何浏览器标签所分心。 4。Slack Slack采用了Electron框架构建,鉴于其高性能表现和无框架外观,将带来与浏览器完全不同的体验方式。对于寻求更集中的工作空间的团队来说,SlackDesktop绝对是最适合的应用程序之一。 虽然SlackDesktop融合了很多技术,但大多数资源文件和代码都是远程加载的,它们结合了Chromium的渲染引擎和Node。js运行时和模块系统。 5。WhatsApp WhatsApp作为下载量最高的Messenger应用程序,也是基于Electron框架构建的。Electron帮助WhatsApp开发人员以低廉的成本完成了几乎所有工作,并通过更加简化和创新的技术,为用户带来全新的桌面体验方式。Electron架构实现 Electron基本文件结构 Electron有一个基本的文件结构,类似于我们在创建网页时使用的文件结构: electronquickstartindex。html这是一个HTML5网页,目的用于提供画布(canvas)main。js创建窗口并处理系统事件package。json是我们应用程序的启动脚本。它将在主进程中运行,并包含有关应用程序的所有信息render。js处理应用程序的渲染过程Electron的架构主要分为两部分:主进程和渲染进程 回顾以往的web开发,我们的代码,无论是HTML、CSS还是Javascript,都是运行在浏览器沙盒中的,我们无法越过浏览器的权限访问系统本身的资源,代码的能力被限制在了浏览器中。浏览器之所以这么做,是为了安全的考虑。设想一下,我们在使用浏览器的时候,会打开各式各样不同来源的网站,如果JavaScript代码有能力访问并操作本地操作系统的资源,那将是多么可怕的事情。 假设:你在某天不小心打开了一个恶意的网站,可能你存储在硬盘上的文件就被偷走了(都用不着去修电脑)。 但我们要开发的是桌面应用程序,如果无法访问到本地的资源肯定是不行的。Electron将nodejs巧妙的融合了进来,让nodejs作为整个程序的管家。管家拥有较高的权限,可以访问和操作本地资源,使用原本在浏览器中不提供的高级API。同时管家也管理着渲染进程窗口的创建和销毁。所以,我们将这个管家称之为主进程。在使用Electron开发的程序中,会使用main。js作为程序的主入口,该文件内代码执行的内容,就是主进程中执行的内容。 主进程 主进程控制应用程序的生命周期。Electron用来运行package。json的main脚本的进程被称为主进程。在主进程中运行的脚本通过创建web页面来展示用户界面。它内置了完整的Node。jsAPI,主要用于打开对话框以及创建渲染进程。此外,主进程还负责处理与其他操作系统交互、启动和退出应用程序。 主进程就像是应用程序的管家,负责管理整个应用程序的生命周期以及所有渲染进程的创建。 按照惯例,主进程位于名为main。js的文件中,你可以通过在package。json文件中修改配置属性来更改主进程文件。 比如,我们可以打开package。json并更改配置属性:main:main。js,main:mainTest。js, 请注意,Electron有且只有一个主进程。且主进程销毁时,所有渲染进程也将一并销毁。在chrome浏览器的默认策略下,每一个tab都是独立的进程,Electron也正是利用了这一策略。渲染进程 渲染进程是应用程序中的浏览器窗口。与主进程不同,Electron可以有许多渲染进程,且每个进程都是独立的。由于Electron使用了Chromium来展示web页面,所以Chromium的多进程架构也被使用到。每个Electron中的web页面运行在它自己的渲染进程中。 正是因为每个渲染进程都是独立的,因此一个崩溃不会影响另外一个,这些要归功于Chromium的多进程架构。如何保持进程通信? 即便Electron中的所有进程同时存在并保持独立运行,但他们仍然需要以某种方式进行沟通,尤其是在他们负责不同任务的时候。 为了保持进程通信,Electron有一个进程间通信系统(IPC也就是内部进程通信)。你可以使用IPC在主进程和渲染进程之间传递信息。在主进程中global。sharedObject{someProperty:defaultvalue}在第一个页面中require(electron)。remote。getGlobal(sharedObject)。somePropertynewvalueCopy在第二个页面中console。log(require(electron)。remote。getGlobal(sharedObject)。someProperty) Electron进程通信的实现方式:主进程使用BrowserWindow实例创建页面。每个BrowserWindow实例都在自己的渲染进程里运行页面。当一个BrowserWindow实例被销毁后,相应的渲染进程也会被终止。主进程管理所有的web页面和它们对应的渲染进程。每个渲染进程都是独立的,它只关心它所运行的web页面。在页面中调用与GUI相关的原生API是不被允许的,因为在web页面里操作原生的GUI资源是非常危险的,而且容易造成资源泄露。如果你想在web页面里使用GUI操作,其对应的渲染进程必须与主进程进行通讯,请求主进程进行相关的GUI操作。 说句题外话:在两个网页(渲染进程)间共享数据最简单的方法是使用浏览器中已经实现的HTML5API。其中比较好的方案是用StorageAPI,localStorage,sessionStorage或者IndexedDB,但这些不是今天的主题。如何构建Electron系统架构? 为了降低构建整个Chromium带来的复杂度,Electron通过libchromiumcontent来访问Chromium的ContentAPI。libchromiumcontent是一个独立的、引入了ChromiumContent模块及其所有依赖的共享库。用户不需要一个强劲的机器来构建Electron。 Electron只用了Chromium的渲染库而不是其全部组件。这使得升Chromium更加容易,但也意味着Electron缺少了GoogleChrome里的一些浏览器相关的特性。打包 原来打包步骤略微繁琐,如今由于社区发展,产生了很多优秀的打包工具,让我们可以不用关注很多细节,(比如asar)在主进程中global。sharedObject{someProperty:defaultvalue}在第一个页面中require(electron)。remote。getGlobal(sharedObject)。somePropertynewvalueCopy在第二个页面中console。log(require(electron)。remote。getGlobal(sharedObject)。someProperty)main端ipcMain。on(readFile,(event,{filePath}){contentcontentfs。readFileSync(filePath,utf8);event。sender。send(readFileSuccess,{content});});renderer端ipcRenderer。on(readFileSuccess,(event,{content}){console。log(content:{content});});ipcRender。send(readFile,{filePath:pathtofile,}); 我们仅需做的:将app的目录结构整理好,提供对应的资源,如icon等,然后使用工具制作镜像即可将资源打包成为各个平台下的APP应用。 打包工具的选择 通常情况下,我们选择Electronbuilder(跨平台支持性较好,上手成本低)Electron快速上手实践 这里我们将以SpreadJS的一个应用为例,展示如何将Web应用转换为Electron桌面应用,在线观看地址:http:live。vhall。com878864086 注意事项:打包的信息都在package。json中配置,build字段Electronbuilder使用nsis将我们的文件夹制作成exe,(NullsoftScriptableInstallSystem)nsis本身也是非常复杂和可值得研究的一门技术,在这里我们只要简单使用它提供的参数即可备注Electron目前不支持安卓和ios(官宣)(所以和手机端的混合应用开发不相关)app。makeSingleInstanceapi实现程序互斥(即,同一时间只有一个主程序,不支持开启多个)跨域:在BrowserWindow中的webPreferences中设置webSecurity:false即可(但实际上非常不安全,官方有解释)数据库:和node本身处理数据库相差无几生命周期:正常流程会触发的生命周期如下 willfinishlaunching:当应用程序完成基础的启动的时候被触发 webcontentscreated:webContents被创建完成 browserwindowcreated:BrowserWindow被创建完成 ready:当Electron完成初始化时被触发 remoterequire:引入remote时被调用 beforequit:在应用程序开始关闭窗口之前触发 willquit:当所有窗口都已关闭并且应用程序将退出时发出 quit:在应用程序退出时发出 windowallclosed:当所有的窗口都被关闭时触发 这里要注意如果是进程杀死退出的所有都不触发,如果是cmdQ或者开发者使用app。quit()退出的 windowallclosed是不会被触发的,基本操作一般在ready中处理进程相关: gpuprocesscrashed:当gpu进程崩溃或被杀时触发。其他: browserwindowfocus:在browserWindow获得焦点时发出 browserwindowblur:在browserWindow失去焦点时发出Electron打包配置build:{appId:your。id,appidproductName:程序名称,程序名称files:〔打包需要的不过滤的文件build,main。js,nodemodules〕,directories:{output:。distout,打包输出的目录app:。,package所在路径buildResources:assets},nsis:{oneClick:false,是否需要点击安装,自动更新需要关掉allowToChangeInstallationDirectory:true,是否能够选择安装路径perMachine:true是否需要辅助安装页面},win:{target:〔{target:nsis,输出目录的方式arch:〔输出的配置ia32或者x64x86x64}〕,publish:〔自动更新的配置{provider:generic,自己配置更新的服务器要选genericurl:http:127。0。0。1:8080updata更新配置的路径}}} 以上就是本文的主要内容。 参考资料 原文链接:https:www。freecodecamp。orgchinesenewsspreadjselectronfrominitiationtopractice