快速入門
Electron 可以讓你使用純 JavaScript 調(diào)用豐富的原生 APIs 來(lái)創(chuàng)造桌面應(yīng)用。你可以把它看作一個(gè)專注于桌面應(yīng)用的 Node.js 的變體,而不是 Web 服務(wù)器。
這不意味著 Electron 是綁定了 GUI 庫(kù)的 JavaScript。相反,Electron 使用 web 頁(yè)面作為它的 GUI,所以你能把它看作成一個(gè)被 JavaScript 控制的,精簡(jiǎn)版的 Chromium 瀏覽器。
主進(jìn)程
在 Electron 里,運(yùn)行 package.json
里 main
腳本的進(jìn)程被稱為主進(jìn)程。在主進(jìn)程運(yùn)行的腳本可以以創(chuàng)建 web 頁(yè)面的形式展示 GUI。
渲染進(jìn)程
由于 Electron 使用 Chromium 來(lái)展示頁(yè)面,所以 Chromium 的多進(jìn)程結(jié)構(gòu)也被充分利用。每個(gè) Electron 的頁(yè)面都在運(yùn)行著自己的進(jìn)程,這樣的進(jìn)程我們稱之為渲染進(jìn)程。
在一般瀏覽器中,網(wǎng)頁(yè)通常會(huì)在沙盒環(huán)境下運(yùn)行,并且不允許訪問(wèn)原生資源。然而,Electron 用戶擁有在網(wǎng)頁(yè)中調(diào)用 Node.js 的 APIs 的能力,可以與底層操作系統(tǒng)直接交互。
主進(jìn)程與渲染進(jìn)程的區(qū)別
主進(jìn)程使用 BrowserWindow
實(shí)例創(chuàng)建頁(yè)面。每個(gè) BrowserWindow
實(shí)例都在自己的渲染進(jìn)程里運(yùn)行頁(yè)面。當(dāng)一個(gè) BrowserWindow
實(shí)例被銷毀后,相應(yīng)的渲染進(jìn)程也會(huì)被終止。
主進(jìn)程管理所有頁(yè)面和與之對(duì)應(yīng)的渲染進(jìn)程。每個(gè)渲染進(jìn)程都是相互獨(dú)立的,并且只關(guān)心他們自己的頁(yè)面。
由于在頁(yè)面里管理原生 GUI 資源是非常危險(xiǎn)而且容易造成資源泄露,所以在頁(yè)面調(diào)用 GUI 相關(guān)的 APIs 是不被允許的。如果你想在網(wǎng)頁(yè)里使用 GUI 操作,其對(duì)應(yīng)的渲染進(jìn)程必須與主進(jìn)程進(jìn)行通訊,請(qǐng)求主進(jìn)程進(jìn)行相關(guān)的 GUI 操作。
在 Electron,我們提供幾種方法用于主進(jìn)程和渲染進(jìn)程之間的通訊。像 ipcRenderer
和 ipcMain
模塊用于發(fā)送消息, remote 模塊用于 RPC 方式通訊。這些內(nèi)容都可以在一個(gè) FAQ 中查看 how to share data between web pages。
打造你第一個(gè) Electron 應(yīng)用
大體上,一個(gè) Electron 應(yīng)用的目錄結(jié)構(gòu)如下:
your-app/
├── package.json
├── main.js
└── index.html
package.json
的格式和 Node 的完全一致,并且那個(gè)被 main
字段聲明的腳本文件是你的應(yīng)用的啟動(dòng)腳本,它運(yùn)行在主進(jìn)程上。你應(yīng)用里的 package.json
看起來(lái)應(yīng)該像:
{
"name" : "your-app",
"version" : "0.1.0",
"main" : "main.js"
}
注意:如果 main
字段沒有在 package.json
聲明,Electron會(huì)優(yōu)先加載 index.js
。
main.js
應(yīng)該用于創(chuàng)建窗口和處理系統(tǒng)事件,一個(gè)典型的例子如下:
const {app, BrowserWindow} = require('electron')
const path = require('path')
const url = require('url')
// 保持一個(gè)對(duì)于 window 對(duì)象的全局引用,如果你不這樣做,
// 當(dāng) JavaScript 對(duì)象被垃圾回收, window 會(huì)被自動(dòng)地關(guān)閉
let win
function createWindow () {
// 創(chuàng)建瀏覽器窗口。
win = new BrowserWindow({width: 800, height: 600})
// 加載應(yīng)用的 index.html。
win.loadURL(url.format({
pathname: path.join(__dirname, 'index.html'),
protocol: 'file:',
slashes: true
}))
// 打開開發(fā)者工具。
win.webContents.openDevTools()
// 當(dāng) window 被關(guān)閉,這個(gè)事件會(huì)被觸發(fā)。
win.on('closed', () => {
// 取消引用 window 對(duì)象,如果你的應(yīng)用支持多窗口的話,
// 通常會(huì)把多個(gè) window 對(duì)象存放在一個(gè)數(shù)組里面,
// 與此同時(shí),你應(yīng)該刪除相應(yīng)的元素。
win = null
})
}
// Electron 會(huì)在初始化后并準(zhǔn)備
// 創(chuàng)建瀏覽器窗口時(shí),調(diào)用這個(gè)函數(shù)。
// 部分 API 在 ready 事件觸發(fā)后才能使用。
app.on('ready', createWindow)
// 當(dāng)全部窗口關(guān)閉時(shí)退出。
app.on('window-all-closed', () => {
// 在 macOS 上,除非用戶用 Cmd + Q 確定地退出,
// 否則絕大部分應(yīng)用及其菜單欄會(huì)保持激活。
if (process.platform !== 'darwin') {
app.quit()
}
})
app.on('activate', () => {
// 在這文件,你可以續(xù)寫應(yīng)用剩下主進(jìn)程代碼。
// 也可以拆分成幾個(gè)文件,然后用 require 導(dǎo)入。
if (win === null) {
createWindow()
}
})
// 在這文件,你可以續(xù)寫應(yīng)用剩下主進(jìn)程代碼。
// 也可以拆分成幾個(gè)文件,然后用 require 導(dǎo)入。
最后,你想展示的 index.html
:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Hello World!</title>
</head>
<body>
<h1>Hello World!</h1>
We are using node <script>document.write(process.versions.node)</script>,
Chrome <script>document.write(process.versions.chrome)</script>,
and Electron <script>document.write(process.versions.electron)</script>.
</body>
</html>
運(yùn)行你的應(yīng)用
一旦你創(chuàng)建了最初的 main.js
, index.html
和 package.json
這幾個(gè)文件,你可能會(huì)想嘗試在本地運(yùn)行并測(cè)試,看看是不是和期望的那樣正常運(yùn)行。
electron-prebuilt
electron
是一個(gè) npm
模塊,包含所使用的 Electron 預(yù)編譯版本。
如果你已經(jīng)用 npm
全局安裝了它,你只需要按照如下方式直接運(yùn)行你的應(yīng)用:
electron .
如果你是局部安裝,那運(yùn)行:
macOS / Linux
$ ./node_modules/.bin/electron .
Windows
$ .\node_modules\.bin\electron .
手工下載 Electron 二進(jìn)制文件
如果你手工下載了 Electron 的二進(jìn)制文件,你也可以直接使用其中的二進(jìn)制文件直接運(yùn)行你的應(yīng)用。
Windows
$ .\electron\electron.exe your-app\
Linux
$ ./electron/electron your-app/
macOS
$ ./Electron.app/Contents/MacOS/Electron your-app/
Electron.app
里面是 Electron 發(fā)布包,你可以在 這里 下載到。
以發(fā)行版本運(yùn)行
在你完成了你的應(yīng)用后,你可以按照 應(yīng)用部署 指導(dǎo)發(fā)布一個(gè)版本,并且以已經(jīng)打包好的形式運(yùn)行應(yīng)用。
參照下面例子
復(fù)制并且運(yùn)行這個(gè)庫(kù) electron/electron-quick-start
。
注意:運(yùn)行時(shí)需要你的系統(tǒng)已經(jīng)安裝了 Git 和 Node.js(包含 npm)。
# 克隆這倉(cāng)庫(kù)
$ git clone https://github.com/electron/electron-quick-start
# 進(jìn)入倉(cāng)庫(kù)
$ cd electron-quick-start
# 安裝依賴庫(kù)并運(yùn)行應(yīng)用
$ npm install && npm start
更多 apps 例子,查看 electron 社區(qū)創(chuàng)建的 list of boilerplates。