Electron是一个构建跨平台桌面应用程序的框架。仅使用JavaScript、HTML和CSS,您就可以快速轻松地构建本机应用程序。这对于想要涉足其他领域的开发者来说是一大福音。项目介绍仓库地址:lin-xin/calculator这里我通过Electron实现了一个类似iPhone的计算器。横屏和竖屏可以通过菜单切换,横屏有更多的计算量。对于JavaScript进行浮点计算,精度损失是一个很大的问题,所以我使用第三方库math.js来解决这个精度问题。尽可能实现和iPhone一样的计算:1+2×3=73+=6(再按=等于9)0.1+0.2=0.3(浮点精度处理)不过我不说了下面关于计算器,都是用到的Electron的知识点。生命周期通过主进程中的app模块来控制整个应用的生命周期。当Electron完成初始化时触发ready事件:app.on('ready',()=>{//createwindow,loadpage,etc.})当所有窗口关闭时触发window-all-closed事件:app.on('window-all-closed',()=>{if(process.platform!=='darwin'){app.quit();//退出应用}})在开发中发现,无监控在这种情况下,打包的应用程序关闭后,进程仍然存在,会占用系统的内存。Window本来我们的html只是在浏览器中显示,而electron提供了一个BrowserWindow模块用于创建和控制浏览器窗口,我们的页面就显示在这样一个窗口中。创建的窗口通过关键字new实例化返回win对象,win对象有丰富的方法来控制窗口。win=newBrowserWindow({width:390,//窗口宽度height:670,//窗口高度fullscreen:false,//不允许全屏resizable:false//不允许改变窗口大小,否则布局会乱向上});创建后加载页面窗口为空白,可通过win.loadURL()加载要显示的页面。constpath=require('path');consturl=require('url');win.loadURL(url.format({//加载本地文件pathname:path.join(__dirname,'index.html'),protocol:'file',slashes:true}))也可以直接加载远程链接win.loadURL('http://blog.gdfengshuo.com');menu桌面应用菜单栏是最常见的功能。Electron提供Menu模块创建原生应用菜单和上下文菜单,consttemplate=[//创建菜单模板{label:'view',submenu:[{label:'verticalscreen',type:'radio',checked:true},//type属性使菜单可选为radio{label:'horizo??ntalscreen',type:'radio',checked:false},{label:'reload',role:'reload'},{label:'Quit',role:'quit'},]}]constmenu=Menu.buildFromTemplate(template);//通过模板返回菜单的数组Menu.setApplicationMenu(menu);//设置数组为子菜单中的菜单,在竖屏或横屏上进行一些点击操作,可以监听子菜单的点击事件。consttemplate=[{label:'view',submenu:[{label:'横屏'click:()=>{//监听横屏的点击事件win.setSize(670,460);//设置宽度和窗口的高度}}]}]主进程与渲染进程的通信虽然可以设置点击横屏时窗口的宽高,但是如何触发页面中的方法需要主进程之间的通信进程和渲染进程。主进程可以理解为main.js用来写electronapi的是主进程,渲染进程是渲染的页面。ipcMainipcMain模块可以在主进程中使用,它控制渲染进程(网页)发送的异步或同步消息。const{ipcMain}=require('electron')ipcMain.on('send-message',(event,arg)=>{event.sender.send('reply-message','helloworld')})ipcMain监控发送-message事件,当消息到达时,可以调用event.sender.send回复异步消息,将reply-message事件发送给渲染进程,或者带参数发送。在渲染过程中,ipcRenderer可以调用ipcRenderer模块向主进程发送同步或异步消息,也可以接收主进程的响应。const{ipcRenderer}=require('electron')ipcRenderer.on('reply-message',(event,arg)=>{console.log(arg);//helloworld})ipcRenderer.send('anything','大家好');ipcRenderer可以监听主进程的reply-message事件并获取运行的参数,也可以使用send()方法向主进程发送消息。webContentswebContents是一个事件发送者,负责渲染和控制网页,也是BrowserWindow对象的一个??属性。ipcMain中的event.sender返回的是发送消息的webContents对象,所以里面包含了发送消息的send()方法。constwin=BrowserWindow.fromId(1);//fromId()方法查找ID为1的窗口win.webContents.on('todo',()=>{win.webContents.send('done','welldone!')})remoteremote模块提供了一种在渲染器进程(网页)和主进程之间进行进程间通信(IPC)的简单方法。在Electron中,有很多模块只存在于主进程中。如果要调用这些模块的方法,需要通过ipc模块向主进程发送消息,让主进程调用这些方法。而使用remote模块,可以在渲染进程中调用这些只存在于主进程对象中的方法。const{remote}=require('electron')constBrowserWindow=remote.BrowserWindow//访问主进程中的BrowserWindow模块letwin=newBrowserWindow();//其他操作同主进程,只是remote模块可以访问主进程内置模块有自己的一些方法。remote.require(module)//返回主进程中执行require(module)返回的对象remote.getCurrentWindow()//返回网页所属的BrowserWindow对象remote.getCurrentWebContents()//返回的WebContents对象网页remote.getGlobal(name)//返回主进程中名为name的全局变量(即global[name])remote.process//返回主进程中的进程对象,相当于remote.getGlobal('process')但有cacheshell模块使用系统默认应用程序来管理文件和URL,并且在主进程和渲染器进程中都可用。在菜单中,我想点击子菜单打开一个网站,那么我可以使用shell.openExternal()方法,该URL将在默认浏览器中打开const{shell}=require('electron');shell.openExternal('https://github.com/lin-xin/calculator');打包应用程序其实把程序打包成桌面应用程序是比较麻烦的。我在这里尝试了electron-packager和electron-builder。electron-packagerelectron-packager可以将项目打包成可以在各个平台上直接运行的程序,而不是安装包。首先使用npm安装:npminstallelectron-packager-S运行打包命令:electron-packager./calculator--platform=win32--overwrite--icon=./icon.ico将包括node_modules在内的项目文件一起打包进去,当然可以通过–ignore=node_modules忽略文件,但是如果项目中使用了第三方库,如果忽略了,会找不到文件,会报错。正确的做法是严格区分dependencies和devDependencies。打包的时候只会打包依赖库,用cnpm安装的.0.xx@xxx文件会有很多,也会打包,所以最好不要用cnpmelectron-builderelectron-builder是基于electron-packager打包的程序,然后进行安装处理,将工程打包成安装文件。安装:npminstallelectron-builder-S打包:electron-builder–win安装过程中,第一次下载electron可能会出现连接超时,可以用yarn试试。另外winCodeSign和nsis-resources也有可能失效,可以参考electron-builder/issues解决。综上所述,Electron还是比较好用的。您可以创建一个简单的桌面应用程序,但打包过程更容易遇到问题。网上好像有一个一键打包的工具,不过我没试过。以上也是基于windows7的做法,毕竟没有Mac是不行的。【本文为专栏作家“林欣”原创稿件,转载请微信♂联系作者获得授权】点此查看该作者更多好文
