Electron 快速入門

簡介

Electron 是一個可使用 Web 技術如 JavaScript、HTML 和 CSS 來建立跨平臺原生桌面應用的框架。藉助 Electron,咱們可使用純 JavaScript 來調用豐富的原生 APIs。javascript

Electron用 web 頁面做爲它的 GUI,而不是綁定了 GUI 庫的 JavaScript。它結合了 Chromium、Node.js 和用於調用操做系統本地功能的 APIs(如打開文件窗口、通知、圖標等)。html

Electron-Quick-Start-00

如今已經有不少由 Electron 開發應用,好比 AtomInsomniaVisual Studio Code 等。查看更多使用 Electron 構建的項目能夠訪問 [Apps Built on Electron
](https://electron.atom.io/apps/)前端

安裝

安裝 electron 以前,須要安裝 Node.js。若是沒有安裝,推薦使用 nvm 等 Node.js 版本管理工具進行安裝/java

而後建議修改 electron 的源爲國內源:node

$ export ELECTRON_MIRROR="https://npm.taobao.org/mirrors/electron/"

否則會出現以下錯誤:git

Error: connect ETIMEDOUT 54.231.50.42:443
    at Object.exports._errnoException (util.js:1016:11)
    at exports._exceptionWithHostPort (util.js:1039:20)
    at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1138:14)

安裝 electron:github

$ npm install electron -g

進程

Electron 的進程分爲主進程和渲染進程。web

主進程

在 electron 裏面,運行 package.json 裏面 main 腳本的進程成爲主進程。主進程控制整個應用的生命週期,在主進程中能夠建立 Web 形式的 GUI,並且整個 Node API 是內置其中。npm

渲染進程

每一個 electron 的頁面都運行着本身的進程,稱爲渲染進程。json

主進程與渲染進程的聯繫及區別

主進程使用 BrowserWindow 實例建立頁面。每一個 BrowserWindow 實例都在本身的渲染進程裏運行頁面。當一個 BrowserWindow 實例被銷燬後,相應的渲染進程也會被終止。

主進程管理全部頁面和與之對應的渲染進程。每一個渲染進程都是相互獨立的,而且只關心他們本身的頁面。

在 electron 中,頁面不直接調用底層 APIs,而是經過主進程進行調用。因此若是你想在網頁裏使用 GUI 操做,其對應的渲染進程必須與主進程進行通信,請求主進程進行相關的 GUI 操做。

在 electron 中,主進程和渲染進程的通訊主要有如下幾種方式:

  • ipcMain、ipcRender

  • Remote 模塊

進程通訊將稍後詳細介紹。

打造第一個 Electron 應用

如下全部代碼能夠在 https://github.com/nodejh/electron-quick-start 找到。

一個最簡單的 electron 應用目錄結構以下:

electron-demo/
├── package.json
├── main.js
└── index.html

package.json 與 Node.js 的徹底一致,因此咱們可使用 npm init 來生成。而後將 "main": "index.js" 修改成 "main": "main.js"。之因此命名爲 main.js,主要是爲了與主進程這個概念對應。

main.js

建立 main.js 文件並添加以下代碼:

const electron = require('electron');

const {
  app, // 控制應用生命週期的模塊
  BrowserWindow, // 建立原生瀏覽器窗口的模塊
} = electron;

// 保持一個對於 window 對象的全局引用,若是不這樣作,
// 當 JavaScript 對象被垃圾回收, window 會被自動地關閉
let mainWindow;

function createWindow() {
  // 建立瀏覽器窗口。
  mainWindow = new BrowserWindow({width: 800, height: 600});

  // 加載應用的 index.html。
  // 這裏使用的是 file 協議,加載當前目錄下的 index.html 文件。
  // 也可使用 http 協議,如 mainWindow.loadURL('http://nodejh.com')。
  mainWindow.loadURL(`file://${__dirname}/index.html`);

  // 啓用開發工具。
  mainWindow.webContents.openDevTools();

  // 當 window 被關閉,這個事件會被觸發。
  mainWindow.on('closed', () => {
    // 取消引用 window 對象,若是你的應用支持多窗口的話,
    // 一般會把多個 window 對象存放在一個數組裏面,
    // 與此同時,你應該刪除相應的元素。
    mainWindow = null;
  });
}

// Electron 會在初始化後並準備
// 建立瀏覽器窗口時,調用這個函數。
// 部分 API 在 ready 事件觸發後才能使用。
app.on('ready', createWindow);

// 當所有窗口關閉時退出。
app.on('window-all-closed', () => {
  // 在 macOS 上,除非用戶用 Cmd + Q 肯定地退出,
  // 不然絕大部分應用及其菜單欄會保持激活。
  if (process.platform !== 'darwin') {
    app.quit();
  }
});

app.on('activate', () => {
  // 在 macOS 上,當點擊 dock 圖標而且該應用沒有打開的窗口時,
  // 絕大部分應用會從新建立一個窗口。
  if (mainWindow === null) {
    createWindow();
  }
});

關於 appBrowserWindow 對象和實例的更多用法可參考 electron 的文檔:

index.html

而後編輯須要展現的 index.html

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>Hello World!</title>
    <style media="screen">
      .version {
        color: red;
      }
    </style>
  </head>
  <body>
    <h1>Hello World!</h1>
    We are using Node.js
    <span id="version-node" class="version"></span>
    and Electron
    <span id="version-electron" class="version"></span>
    <script type="text/javascript">
      console.log('process: ', process);
      var versionNode = process.version;
      var versionElectron = process.versions['electron'];
      document.getElementById('version-node').innerText = versionNode
      document.getElementById('version-electron').innerText = versionElectron
    </script>
  </body>
</html>

在這個例子中,咱們顯示出了 electron 使用的 Node.js 版本和 electron 的版本。index.html 跟網頁的 HTML 一摸同樣,只是多了一些 electron 的全局對象。

運行

由於前面已經全局安裝了 electron,因此咱們可使用 electron 命令來運行項目。在 electron-demo/ 目錄裏面運行下面的命令:

$ electron .

而後會彈出一個 electron 應用客戶端,如圖所示:

Electron-Quick-Start-01

由於在主進程中啓用了開發模式 mainWindow.webContents.openDevTools(),因此默認啓動開發者工具。

若是是局部安裝的 electron,即 npm install --save electron,則能夠運行下面的命令來啓動應用:

$ ./node_modules/.bin/electron .

進行通訊

對於 electron 來講,主進程和渲染進程直接的通訊是必不可少的。

前面提到過 electron 進程間的通訊的方式主要有兩種,一種是用於發送消息的 ipcMainipcRenderer 模塊,一種用於 RPC 的 remote 模塊。

如今假設一個業務場景,用戶在頁面中輸入文本消息,渲染進程將消息發送給主進程,主進程處理後將處理結果返回給頁面。爲了方便起見,主進程的處理就假設爲翻轉文本。固然,這個功能在前端徹底能夠實現,這裏只是爲了演示進程通訊。

ipcMain 和 ipcRenderer

首先在渲染進程中添加一個輸入框和一個按鈕,並實現點擊按鈕獲取輸入框的內容。而後使用 ipcRenderer 發送消息。主進程接收到消息並處理以後,會返回處理結果。因此渲染進程中還須要接收主進程的消息。

修改 index.html,添加下面的代碼:

<!-- 在 body 部分添加一個輸入框和按鈕 -->
<div>
  <input type="text" id="message" name="" value="">
  <br/>
  <button type="button" id="button" name="button">click me</button>
</div>

<script type="text/javascript">
  // ...

  // 添加下面的代碼。
  // 引入 ipcRenderer 模塊。
  var ipcRenderer = require('electron').ipcRenderer;
  document.getElementById('button').onclick = function () {
    var message = document.getElementById('message').value;
    // 使用 ipcRenderer.send 向主進程發送消息。
    ipcRenderer.send('asynchronous-message', message);
  }

  // 監聽主進程返回的消息
  ipcRenderer.on('asynchronous-reply', function (event, arg) {
    alert(arg);
  });
</script>

接下來在主進程中接收渲染進程的消息,並進行處理(翻轉字符串),而後將處理結果發送給主進程。修改 main.js 以下:

//...

// 監聽渲染進程發送的消息
ipcMain.on('asynchronous-message', (event, arg) => {
  const reply = arg.split('').reverse().join('');
  console.log('reply: ', reply);
  // 發送消息到主進程
  event.sender.send('asynchronous-reply', reply);
});

而後從新運行項目。在頁面的輸入框內輸入字符,點擊按鈕,就能彈出以下的彈出框,說明渲染進程與主進程通訊成功:

http://oh1ywjyqf.bkt.clouddn.com/Electron-Quick-Start-02.png

remote

remote 模塊提供了一種在渲染進程(網頁)和主進程之間進行進程間通信(IPC)的簡便途徑。

使用 remote 模塊,咱們能夠很方便地調用主進程對象的方法,而不須要發送消息。

index.html<script> 標籤中添加以下代碼:

// 引入 remote 模塊
var remote = require('electron').remote;
// 獲取主進程中的 BrowserWindow 對象
var BrowserWindow = remote.BrowserWindow;
// 建立一個渲染進程
var win = new BrowserWindow({ width: 200, height: 150 });
win.loadURL('http://nodejh.com');

而後使用 ctr + r 組合鍵刷新應用,就會看到建立出的一個新窗口。

打包

Electron 應用開發完成以後,還須要將其打包成對應平臺的客戶端。經常使用的打包工具備 electron-packagerasar

這裏以 electron-packager 爲例。首先全局安裝 electron-packager:

$ npm install electron-packager -g

而後在項目中安裝 electron:

$ npm install electron --save-dev

而後打包:

$ electron-packager . electron-demo

總結

本文首先對 electron 作了簡單的介紹,而後講解了 electron 進程的概念,其進程包括主進程和渲染進程。而後建立了一個簡單的 electron 應用,並經過實現一個簡單的應用場景,對 electron 進程間的通訊作了實踐。整體來講,使用 electron 建立桌面客戶端的開發體驗跟寫 Node.js 和網頁差很少。但本文對內置模塊好比 app、ipcMain、ipcRender、remote 等的介紹比較粗淺,涉及到一些內置模塊的使用,還須要繼續查詢 electron 的官方文檔,只有實踐越多,才能越熟悉。

https://github.com/nodejh/nodejh.github.io/issues/39

--

相關文章
相關標籤/搜索