web端能作的事情不少,可是当涉及到操做系统的时候,可能就有点力不从心了。前段时间在开发一个web系统的时候,就遇到了相似的状况。咱们须要获取电脑操做系统的一些信息,好比mac地址等。咱们的web系统是彻底放在服务器上,经过浏览器来运行的,可是经过web端并不能直接实现咱们想要的效果。javascript
问题就是留给人们来解决的。通过同事之间的讨论,由于系统自己并不复杂,并且要进行快速的开发。决定用Electron + 原web系统的页面,来解决涉及操做系统信息的问题。html
这篇文章总结了我在使用Electron 时所遇到的一些问题和解决方法。前端
使用 JavaScript, HTML 和 CSS 构建跨平台的桌面应用——这是 Electron官网的简介Electron是GitHub开发的一个开源框架。它容许使用Node.js(做为后端)和Chromium(做为前端)完成桌面GUI应用程序的开发。Electron现已被多个开源Web应用程序用于前端与后端的开发,著名项目包括GitHub的Atom和微软的Visual Studio Code。——知乎vue
能够简单的理解为Electron为web项目套上了Node.js环境的壳,使得咱们能够调用Node.js的丰富的API。这样咱们能够用JavaScript来写桌面应用,拓展不少咱们在web端不能作的事情。java
构建Electron应用很简单,能够直接查看官方文档,也能够利用现有的轮子。基原本说能够分为两大类:模板和命令行工具。这两种方式都有各自的优势,具体选用哪一种方式要根据本身实际的状况来。就拿我来讲,由于我要作的项目本来就有web端的页面了,这些模板基本都不适用,为了赶进度,就直接参考官网入门——打造你的第一个-electron-应用,再加上原有的代码进行构建项目。node
下面为一些经常使用的构建模板与命令行工具react
下面是一个最基础的Electron项目,后续的代码都是在此基础上进行拓展。linux
npm install --save-dev electron
通常结构git
demo/ ├── package.json ├── main.js └── index.html
package.jsongithub
{ "name": "demo", "version": "1.0.0", "description": "electornDemo", "main": "main.js", "scripts": { "start": "electron ." }, "author": "xmanlin", "license": "MIT", "devDependencies": { "electron": "^9.0.0" } }
main.js
const {app, BrowserWindow} = require('electron') app.on('ready', function createWindow () { // 能够建立多个渲染进程 let win = new BrowserWindow({ width: 800, height: 600, }) win.show() // 渲染进程中的web页面能够加载本地文件 win.loadFile('index.html') // 记得在页面被关闭后清除该变量,防止内存泄漏 win.on('closed', function () { win = null }) }) // 页面所有关闭后关闭主进程,不一样平台可能有不一样的处理方式 app.on('window-all-closed', () => { app.quit() })
index.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>demo</title> </head> <body> <div>一个electron项目</div> <script> </script> </body> </html>
在Electron中,主进程和渲染进程的概念是十分重要的,具体能够查看官网介绍:主进程和渲染进程。
package.json
中的main
脚本的进程是主进程。BrowserWindow
类开启一个渲染进程并将这个实例运行在该进程中,当一个BrowserWindow
实例被销毁后,相应的渲染进程也会被终止。模块,在Node.js支持下,能够在页面中和操做系统进行一些底层交互。
在Electron5.0版本后,渲染进程默认是不能调用Node.js的API的,通过设置后才能够:
主进程(main.js)
let win = new BrowserWindow({ width: 800, height: 600, webPreferences: { nodeIntegration: true, //设置为true就能够在这个渲染进程中调用Node.js } })
Electron虽然是用了Chromium,可是想要打开开发者工具并非像浏览器同样,如在windows下默认状况直接按F12。
在Electron中有两种方式打开开发者工具:
第一种是在主进程中进行设置,设置后,启动项目,该渲染进程就默认打开了开发者工具
win.webContents.openDevTools();
第二种能够在渲染进程窗口的菜单栏进行选择View -> Toggle Developer Tools。(或者直接按照上面的快捷键进行操做)
咱们可能在Windows的控制台会出现中文乱码的问题,当咱们在Windows的控制台下输入chcp,能够查看到当前字符编码,常见的gb2312的值是936,utf8的值是65001。这种状况下只要对package.json
进行设置就能解决。
"start": "chcp 65001 && electron ."
主进程和渲染进程之间能够经过ipcRenderer 和 ipcMain模块通讯。
主进程(main.js)
//主进程向渲染进程发送消息,'did-finish-load':当导航完成时发出事件,onload 事件也完成 win.webContents.on('did-finish-load', () => { win.webContents.send('msg', '消息来自主进程') })
渲染进程(index.html)
<script> const {ipcRenderer} = require('electron') ipcRenderer.on('msg', (event, message) => { console.log(message) // 消息来自主进程 }) </script>
渲染进程(index.html)
const {ipcRenderer} = require('electron') ipcRenderer.send('indexMsg','消息来自渲染进程')
主进程(main.js)
const {ipcMain} = require('electron') ipcMain.on('indexMsg',(event,msg) => { console.log(msg) //消息来自渲染进程 })
渲染进程之间的通讯方式有不少种,下面列出几种:
//主进程 global.sharedObject = { user: '' } //渲染进程一 const {remote} = require('electron') remote.getGlobal('sharedObject').user = 'xmanlin' //渲染进程二 const {remote} = require('electron') console.log(remote.getGlobal('sharedObject').user) //xmanlin
下面是ipcRenderer.sendTo()
的参数
ipcRenderer.sendTo(webContentsId, channel, [, arg1][, arg2][, ...]) ipcRenderer.sendTo(windowId, 'ping', 'someThing') //webContentsId : Number //channel : String //...args : any[]
具体用法
主进程(main.js)
//建立一个新的渲染进程 let win2 = new BrowserWindow({ width: 800, height: 600, }) //为渲染进程设置惟一id win2.id = 2
渲染进程1
<script> const {ipcRenderer} = require('electron') //向id为2的渲染进程发送消息 ipcRenderer.sendTo(2,'msg1','来自渲染进程1的消息') </script>
渲染进程2
<script> const {ipcRenderer} = require('electron') ipcRenderer.on('msg1', (event, message) => { console.log(message) // 来自渲染进程1的消息 }) </script>
//主进程 ipcMain.on('msg1', (event, message) => { yourWindow.webContents.send('msg2', message); } //渲染进程1 ipcRenderer.send('msg1', '来自渲染进程1的消息') //渲染进程2 ipcRenderer.on('msg2', (event, message) => { console.log(message) //来自渲染进程1的消息 } )
打包也是必不可少的一步,这里介绍两种比较成熟的打包工具:electron-packager和electron-builder。这两个工具主要是对其进行配置。
咱们能够利用 electron-packager把咱们现有的electron应用打包为exe可执行文件。
先进行安装
npm install electron-packager --save-dev
安装好以后要配置electron-packager的基本命令,下面为官方文档中的基本格式:
electron-packager <sourcedir> <appname> --platform=<platform> --arch=<arch> [optional flags...]
简要的介绍一下各个参数所表明的意思:
platform:肯定了你要构建哪一个平台的应用(Windows、Mac 仍是 Linux)
platform=win32
表明Windowsplatform=darwin
表明Macplatform=linux
表明Linux下面为一个例子,供参考
package.json
"scripts": { "build32": "electron-packager ./ appDemo --platform=win32 --arch=ia32 --out=./app --app-version=1.0.0 --overwrite --icon=./favicon.ico", "build64": "electron-packager ./ appDemo --platform=win32 --arch=x64 --out=./app --app-version=1.0.0 --overwrite --icon=./favicon.ico" }
上面都是打包Windows下的软件,build32打包的为32位,build64打包的为64位。除基本参数外,上面其余参数所表明的意义以下:
electron-builder不只能够打包为exe可执行文件,还能够打包为可安装程序,功能与electron-packager相比也要丰富一些。
官网更为推崇yarn 来进行安装
yarn add electron-builder --dev
固然npm也是能够的
npm install electron-builder --save-dev
而后咱们能够进行配置了
"scripts": { "pack": "electron-builder --dir", "dist": "electron-builder" }, "build": { "productName": "appDemo", // app中文名称 "appId": "appDemoId",// app标识 "directories": { // 打包后输出的文件夹 "buildResources": "resources", "output": "dist/" } "files": [ // 打包后依然保留的源文件 "dist/electron", "node_modules/", "package.json" ], "mac": { // mac打包配置 "target": "dmg", "icon": "icon.ico" }, "win": { // windows打包配置 "target": "nsis", "icon": "icon.ico" }, "dmg": { // dmg文件打包配置 "artifactName": "appDemo.dmg", "contents": [ { "type": "link", "path": "/Applications", "x": 410, "y": 150 }, { "type": "file", "x": 130, "y": 150 } ] }, "nsis": { // nsis文件打包配置 "oneClick": false, "allowToChangeInstallationDirectory": true, // 容许修改安装目录 "allowElevation": true, // 容许请求提高。 若是为false,则用户必须使用提高的权限从新启动安装程序。 "installerIcon": "./build/icons/aaa.ico",// 安装图标 "uninstallerIcon": "./build/icons/bbb.ico",//卸载图标 "installerHeaderIcon": "./build/icons/aaa.ico", // 安装时头部图标 "createDesktopShortcut": true, // 建立桌面图标 "createStartMenuShortcut": true,// 建立开始菜单图标 "shortcutName": "xxxx", // 图标名称 "include": "build/script/installer.nsh", //包含的自定义nsis脚本这个对于构建需求严格得安装过程至关有用。 }, }
在使用electron-builder打包时,也能够指定参数
--mac, -m, -o, --macos macOS打包 --linux, -l Linux打包 --win, -w, --windows Windows打包 --mwl 同时为macOS,Windows和Linux打包 --x64 x64 (64位安装包) --ia32 ia32(32位安装包)
所有参数可参考Command Line Interface (CLI)
关于NSIS,也能够了解一下这种打包方式:electron 打包流程 electron-packager + NSIS
默认最大化
//主进程(main.js) let win = new BrowserWindow({show: false}) win.maximize() win.show()
默认全屏
//主进程(main.js) let win = new BrowserWindow({fullscreen: true})
能够直接参考这篇文章-使用 Electron 自定义菜单,写的比较详细,也能够直接参考官方文档来。固然咱们也能够把自带的菜单栏隐藏掉,而后本身调用写Electron的API写一个菜单栏。例如VSCode就是这么作的,打开VSCode,而后在帮助里面找到切换开发者工具,你可能会发现新世界~。
这个主要是调用Node.js的API,就能够获取系统的mac地址。
var os=require("os"); //获取mac地址 var mac = '' var networkInterfaces=os.networkInterfaces(); for(var i in networkInterfaces){ for(var j in networkInterfaces[i]){ if(networkInterfaces[i][j]["family"]==="IPv4" && networkInterfaces[i][j]["mac"]!=="00:00:00:00:00:00" && networkInterfaces[i][j]["address"]!=="127.0.0.1"){ mac = networkInterfaces[i][j]["mac"] } } }
https://www.electronjs.org/docs
https://blog.csdn.net/weixin_...
https://www.jianshu.com/p/62c...
https://blog.csdn.net/qq_3480...
https://segmentfault.com/a/11...
https://juejin.im/post/5cfd2e...
这篇文章是我到目前为止在学习并应用Electron时所遇到的问题以及所找到的解决办法,但愿对你们有所帮助。如有不足或错误的地方,欢迎指出~