Github 系列文章地址
筆者前兩天心血來潮作了個MACOS下能夠進行OCR圖文識別的小工具,發現Electron 在1.x以後API發生了挺大的變化,估計也是我很久沒碰了,因此打算把這些系列整理下扔出來,有興趣的也能夠關注筆者的ElectronOCR這個實踐項目,自認爲仍是有點用的,不過貌似沒啥人喜歡。javascript
Electron 可讓你使用純 JavaScript 調用豐富的原生 APIs 來創造桌面應用。你能夠把它看做是專一於桌面應用而不是 Web 服務器的io.js 的一個變體。這不意味着 Electron 是綁定了 GUI 庫的 JavaScript。相反,Electron 使用 Web 頁面做爲它的 GUI,因此你能把它看做成一個被 JavaScript 控制的,精簡版的 Chromium 瀏覽器。html
在 Electron 裏,運行 package.json
裏 main
腳本的進程被稱爲主進程。在主進程運行的腳本能夠以建立 web 頁面的形式展現 GUI。java
因爲 Electron 使用 Chromium 來展現頁面,因此 Chromium 的多進程結構也被充分利用。每一個 Electron 的頁面都在運行着本身的進程,這樣的進程咱們稱之爲渲染進程。在通常瀏覽器中,網頁一般會在沙盒環境下運行,而且不容許訪問原生資源。然而,Electron 用戶擁有在網頁中調用 io.js 的 APIs 的能力,能夠與底層操做系統直接交互。node
主進程使用 BroswerWindow 實例建立網頁。每一個 BroswerWindow 實例都在本身的渲染進程裏運行着一個網頁。當一個 BroswerWindow 實例被銷燬後,相應的渲染進程也會被終止。主進程管理全部頁面和與之對應的渲染進程。每一個渲染進程都是相互獨立的,而且只關心他們本身的網頁。因爲在網頁裏管理原生 GUI 資源是很是危險並且容易形成資源泄露,因此在網頁面調用 GUI 相關的 APIs 是不被容許的。若是你想在網頁裏使用 GUI 操做,其對應的渲染進程必須與主進程進行通信,請求主進程進行相關的 GUI 操做。
在 Electron,咱們提供用於在主進程與渲染進程之間通信的 ipc 模塊。而且也有一個遠程進程調用風格的通信模塊 remote。react
electron-api-demos:官方的Electron API示範git
官方文檔的中文翻譯:官方的API中文翻譯github
electron-prebuild
npm install -g electron-prebuilt
若是你已經用 npm
全局安裝了 electron-prebuilt
,你只須要按照以下方式直接運行你的應用:
electron .
若是你是局部安裝,那運行:
./node_modules/.bin/electron .
手工下載 Electron 二進制文件
若是你手工下載了 Electron 的二進制文件,你也能夠直接使用其中的二進制文件直接運行你的應用。
(1)Windows
$ .\electron\electron.exe your-app\
(2)Linux
$ ./electron/electron your-app/
(3)OS X
$ ./Electron.app/Contents/MacOS/Electron your-app/
Electron.app
裏面是 Electron 發佈包,你能夠在這裏下載到。
npm install --save-dev devtron require('devtron').install()
大致上,一個 Electron 應用的目錄結構以下:
your-app/ ├── package.json //通用的node項目的聲明文件 ├── main.js //主進程渲染文件 ├── renderer.js //渲染進程文件 └── index.html //主入口文件
package.json
的格式和 Node 的徹底一致,而且那個被 main
字段聲明的腳本文件是你的應用的啓動腳本,它運行在主進程上。你應用裏的 package.json
看起來應該像:
{ "name" : "your-app", "version" : "0.1.0", "main" : "main.js" }
注意:若是 main
字段沒有在 package.json
聲明,Electron會優先加載 index.js
。
main.js
應該用於建立窗口和處理系統時間,一個典型的例子以下:
/** * Created by apple on 16/6/3. */ const electron = require('electron'); // 用於控制應用生命週期 const {app} = electron; // 用於建立本地窗口 const {BrowserWindow} = electron; //爲Window對象建立一個全局的引用,不然可能被JavaScript的垃圾回收機制自動回收 let win; /** * @function 建立窗口 */ function createWindow() { // 建立相似於瀏覽器的窗口 win = new BrowserWindow({width: 800, height: 600}); // 加載應用入口文件,本文件爲測試文件,所以加載的是測試 win.loadURL(`file://${__dirname}/dist/app.html`); // 啓動調試工具,若是是開發環境下則不須要開啓 win.webContents.openDevTools(); // 設置窗口關閉事件 win.on('closed', () => { //由於上面是設置了一個全局引用,所以這裏須要對該對象解除引用 //若是你的應用支持打開多窗口,能夠把全部的引用存入一個數組中,而後在這裏動態刪除 win = null; }); } // 在基本環境準備好以後的回調 app.on('ready', createWindow); // 全部窗口都關閉以後的回調 app.on('window-all-closed', () => { //在OSX中常常是用戶雖然關閉了主窗口,可是仍然但願使用Menu Bar,所以這裏不進行強行關閉 // On OS X it is common for applications and their menu bar // to stay active until the user quits explicitly with Cmd + Q if (process.platform !== 'darwin') { app.quit(); } }); // 應用被從新激活以後的回調 app.on('activate', () => { // 在Dock中的Menu Bar被點擊以後從新激活應用 if (win === null) { createWindow(); } });
最後,你想展現的 index.html
:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Hello World!</title> </head> <body> <h1>Hello World!</h1> <!-- All of the Node.js APIs are available in this renderer process. --> We are using node <script>document.write(process.versions.node)</script>, Chromium <script>document.write(process.versions.chrome)</script>, and Electron <script>document.write(process.versions.electron)</script>. </body> <script> // You can also require other files to run in this process require('./renderer.js') </script> </html>
實際上,在Electron項目中,關於Hot-Reload等等配置都和筆者在個人Webpack套裝中說起的一系列配置方案。關於這方面的具體實踐能夠參考筆者ElectronOCR這個實戰項目。