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時所遇到的問題以及所找到的解決辦法,但願對你們有所幫助。如有不足或錯誤的地方,歡迎指出~