Electron是什麼以及可以做什麼

2022-11-10 12:02:08

新使用者購買《Electron + Vue 3 桌面應用開發》,加小冊專屬微信群,參與群抽獎,送《深入淺出Electron》、《Electron實戰》作者簽名版。

  • 1等獎:《深入淺出Electron》+《Electron實戰》
  • 2等獎:《深入淺出Electron》
  • 3等獎:《Electron實戰》

抽獎活動是掘金組織的,僅限近幾日加入微信群的新成員(目前人還不多),我負責抽獎、郵寄,11月20日開始抽獎。凡參與抽獎的讀者都有機會中獎。


經濟學中的「有需求就有市場」,在技術領域也不例外,Electron 是應需求而生的,Electron 面世之後,非但滿足了現有大部分的開發需求,還創造了大量的新需求,開闢了一個新的生態。

本章我們從 Electron 的由來講起,講到需求從何而來,它是如何滿足這些需求的。

Electron 的由來

如果想開發一個桌面 GUI 應用軟體,希望其能同時在 Windows、Linux 和 Mac 平臺上執行,可選的技術框架並不多,在早期人們主要用 wxWidgetsGTKQt來做這類工作。

這類框架大都是以 C/C++語言開發,受語言開發效率的限制,開發者想通過它們快速的完成桌面應用的開發工作十分困難。近幾年相繼出現了現代程式語言針對這些框架的繫結庫,諸如 Python、C#、Go 等,大部分都是開源社群提供的,但由於歷史原因,要想用到這些框架的全部特性,還是需要編寫 C/C++程式碼。並且高質量的 Node.js 的繫結庫幾乎沒有,前端程式設計師想通過這類框架開發桌面應用更是難上加難。

Stack Overflow 的聯合創始人 Jeff Atwood 曾經說過,凡能用 JavaScript 實現的,註定會被用 JavaScript 實現。桌面 GUI 應用也不例外,近幾年兩個重量級框架 NW.jsElectron橫空出世,給前端開發人員開啟了這個領域的大門。

這兩個框架都與中國人有極深的淵源,2011 年左右,中國英特爾開源技術中心的王文睿(Roger Wang)希望能用 Node.js 來操作 WebKit,而建立了 node-webkit 專案,這就是 NW.js 的前身。英特爾公司大力支援了這個專案,不但允許王文睿分出一部分精力來做這個開源專案,還給了他招聘名額,允許他招聘其他工程師來一起完成這個專案。
2012 年,故事的另一個主角趙成(Cheng Zhao)加入到王文睿的小組,並對 node-webkit 專案做出了大量的改進。後來趙成離開了英特爾,幫助 github 團隊嘗試把 node-webkit 應用到 Atom 編輯器上,但由於當時 node-webkit 還並不穩定,且 node-webkit 專案的走向也不再受趙成的控制了,這個嘗試最終以失敗告終。
但趙成和 github 團隊並沒有放棄,而是著手開發另一個類似 node-webkit 的專案:Atom Shell,這個專案就是 Electron 的前身,趙成在這個專案上傾注了大量的心血,這也是這個專案後來廣受歡迎的關鍵因素之一,再後來 github 把這個專案開源出來,最終更名為 Electron。

Electron 的價值

Electron 和 NW.js 框架都是基於 Chromium 和 Node.js 實現的,這就使得前端程式設計師可以使用 JavaScript、HTML 和 CSS 知識輕鬆構建跨平臺的桌面應用。

傳統桌面應用開發的難點,現在看來也變得異常容易,比如繪製漂亮的介面可以使用更靈活的 HTML 和 CSS 提供的能力、實現簡單的動效可以用 CSS Animations 或 Web Animations API 來實現。

為了彌補 Node.js 和前端技術存取系統 API 方面的不足,這兩個框架內部都對系統 API 做了封裝,比如:系統對話方塊、系統托盤、系統選單、剪下板等。開發者基於 Electron 開發應用時,可以直接使用 JavaScript 存取這些 API。其他諸如網路存取控制、本地檔案系統的存取控制則由 Node.js 提供支援。這樣開發者就可以使用前端技術開發絕大多數桌面應用的需求了。

前端技術是現如今軟體開發領域應用最廣泛的技術之一。入門門檻非常低、周邊生態繁榮而且歷史悠久。相對於基於 C++庫開發桌面軟體來說,基於 Electron 開發更容易上手且開發效率更高。由於 JavaScript 語言是一門解釋執行的語言,所以 C++語言固有的各種問題都不再是問題,比如:C++沒有垃圾回收機制,開發人員要小心翼翼的控制記憶體,以免造成記憶體洩露。C++語言特性繁多且複雜,學習難度曲線陡峭,需要針對不同平臺進行編譯,應用分發困難等,使用 Electron 開發桌面應用就不用擔心這些問題。

執行效率上,如果前端程式碼寫的足夠優秀,完全可以做到與 C++應用相媲美的使用者體驗,Visual Studio Code 就是先例。另外 Node.js 本身也可以很方便的呼叫 C++擴充套件,Electron 應用內又包含 Node.js 環境,對於一些音視訊編解碼或圖形影象處理需求,可以使用 Node.js 的 C++擴充套件來完成。

隨著幾十年 Web 應用大行其道,Web 前端開發領域的技術生態足夠繁榮。Electron 可以使用幾乎所有的 Web 前端生態領域及 Node.js 生態領域的元件和技術方案。目前釋出到 npmjs.com 平臺上的模組已經超過 90 萬個,覆蓋領域廣、優秀模組繁多且使用非常簡單方便。

在完成 Web 前端開發工作時,開發者需要考慮很多瀏覽器相容的問題,比如:使用者是否使用了低版本的 IE 瀏覽器,是否可以在樣式表內使用 flexbox 彈性盒模型等問題。最終會導致前端開發者束手束腳,寫一些醜陋的相容程式碼以保證自己的工作能在所有終端表現正常。但由於 Electron 內建了 Chromium 瀏覽器,該瀏覽器對標準支援非常好,甚至有些標準尚未通過,Chromium 瀏覽器就已經支援了,所以基於 Electron 開發應用不會遇到這些問題。開發者的自由度得到了最大程度的保護,你幾乎可以在 Electron 中使用所有 HTML5、CSS3 、ES6 標準中定義的 API。

Electron 的原理

Electron 是一個整合專案,它做了如下幾個重要的工作:

  1. 訂製 Chromium,並把訂製版本的 Chromium 整合在 Electron 內部
  2. 訂製 Node.js,並把訂製版本的 Node.js 整合在 Electron 內部
  3. 通過訊息輪訓機制打通 Node.js 和 Chromium 的訊息迴圈
  4. 通過 Electron 的內建模組向開發者提供桌面應用開發必備的 API

Electron 框架的內部原理圖如下所示:

 

 

其中 Chromium 基礎能力 API 可以讓應用渲染開發者提供的 HTML 頁面,讓應用可以在 Cookie 或 IndexedDB 中存取資料,前端開發者都非常熟悉這些能力。

Node.js 基礎能力 API 可以讓開發者讀寫本地磁碟的檔案、通過 socket 存取網路、建立和控制子程序等,Node.js 開發者非常熟悉這些能力。

Electron 內建模組可以讓開發者建立作業系統的托盤圖示、存取作業系統的剪下板、傳送系統通知,同時它還提供了一系列的 API,允許開發者使用 JavaScript 存取 Chromium 的底層能力。

下面我們來看一下 Electron 應用的結構:

 

 

每個 Electron 都是由 1 個主程序、 1 個或多個渲染行程群組成的,開發者的主要工作就是完成主程序的邏輯和渲染程序的邏輯。

Electron 應用啟動時,首先會載入主程序的邏輯,主程序會建立一個或多個視窗,我們暫時可以粗淺的認為一個視窗就代表一個渲染程序,主程序負責管理所有的渲染程序。

視窗內載入的頁面就是開發者要實現的渲染程序的邏輯,我們可以讓渲染程序與主程序通訊,他們之間是通過 IPC 訊息管道進行通訊的。雖然有一些特殊的手段讓兩個渲染程序直接通訊(後面的章節我們會介紹),但大部分時候還是通過主程序來中轉訊息以達到渲染程序間通訊的目的。

Electron 提供的一系列內建模組大部分是專門為主程序的邏輯服務的,比如 app 模組、BrowserWindow 模組和 session 模組等,少量模組是專門為渲染程序的邏輯服務的,比如 ipcRenderer 模組、webFrame 模組等,只有少量模組是兩個程序可以同時使用的,比如:clipboard 模組、desktopCapturer 模組等。我們應該清楚這些模組的勢力範圍,不能在主程序中使用渲染程序的模組,反之也不行。

Electron 的不足

基於 Electron 開發桌面 GUI 應用並不是完美的方案,它也有它的不足,綜合起來說有以下幾點:

第一:打包後的應用體積巨大

一個功能不算多的桌面應用,通過 electron-builder 壓縮打包後至少要 50M。而且如果開發者不做額外的 Hack 工作的話,使用者每次升級應用程式,還要讓使用者再下載一次同樣體積的安裝包。這對於應用分發來說是一個不小的負擔。但隨著網路環境越來越好,使用者磁碟的容積越來越大,此問題給使用者帶來的損失會慢慢被削弱。

第二:版本釋出過快

為了跟進 Chromium (和 Node.js) 的版本釋出節奏,Electron 也有非常頻繁的版本釋出機制,每次 Chromium 的改動,都可能導致 Electron 冒出很多新的問題,甚至穩定版本都有很多未解決的問題。好在關鍵核心功能一直以來都是穩定的。

第三:安全性問題

Electron 把一些有安全隱患的模組和 API 都設定為預設不可用的狀態,但這些模組和 API 都是非常常用的,有的時候開發者不得不開啟這些開關,一旦處理不當,就可能導致他們開發的應用存在安全隱患,給開發者乃至終端使用者帶來傷害。安全問題有很多值得關注的技術細節,以至於 Electron 官方檔案中專門開闢出來一個章節號召程式設計師重視安全問題。

第五:資源消耗較大

Electron 底層基於 Chromium 瀏覽器,資源佔用較多一直以來都是 Chromium 被人詬病的問題,目前來看這個問題還沒有很好的解決辦法,只能依賴 Chromium 團隊對 Chromium 的優化工作了。

第六:效能問題

Electron 本身是多程序多執行緒的框架,但 JavaScript 是單執行緒執行的,如果產品的需求中有大量音視訊編解碼、複雜資料格式化這類 CPU 消耗性的需求,那麼不應該在 Electron 內使用 JavaScript 來實現這些需求,而應該使用 Node.js 的原生模組來實現這些需求。與其說這是一個 Electron 的不足,不如說這是 JavaScript 的不足。

除了以上這些問題外,Electron 還不支援老版本的 Windows 作業系統,比如 Windows XP,在中國還有一些使用者是使用 Windows XP 的,開發者如果需要面向這些使用者,應該考慮使用其他技術方案了。

總結

通過本章內容的講解,我帶領大家學習了 Electron 框架的由來、Electron 框架的價值、Electron 框架的基本原理以及 Electron 框架有哪些不足。

希望讀者通過閱讀本章內容對 Electron 框架有一個基本的認識,知道 Electron 框架可以為我們帶來什麼價值,以及這些價值背後的隱患。

有了這些知識我們就可以更從容的進入 Electron 應用開發的戰場了,還等什麼,隨我來吧。