1. 程式人生 > >初探Electron,從入門到實踐

初探Electron,從入門到實踐

本文由葡萄城技術團隊於部落格園原創並首發

轉載請註明出處:葡萄城官網,葡萄城為開發者提供專業的開發工具、解決方案和服務,賦能開發者。

  在開始之前,我想您一定會有這樣的困惑:標題裡的Electron 是什麼?Electron能做什麼?許多偉大的公司使用Electron框架的原因又是什麼? 帶著這些問題和疑惑,通過本文的介紹,可助您全面地認識Electron這門新興的技術,迅速找到其入門途徑,並理解Electron為何被稱為當下開發桌面App的最佳選擇。   初探Electron
一、Electron是什麼?(為何稱之為“跨平臺桌面瀏覽器”) 前端開發的魅力,在於開發者隨時要面臨全新技術的挑戰!
曾幾何時,作為前端開發者的你可曾想過:如何利用HTML、CSS和JavaScript構建跨平臺的桌面應用程式?藉助 Electron,這項工作將比你想象的更加簡單。 Electron作為一個使用新興技術(包括JavaScript,HTML和CSS)建立桌面應用程式的框架,其負責處理硬體,開發者可以更專注於應用程式的核心並從底層更改其設計。
Electron設計之初便充分結合了當今最好的Web技術,作為一個跨平臺的“整合框架”,它可以輕鬆地與Mac、Windows和Linux相容。而所謂的“整合框架”也就是它將“Chromium”和“Node.js”很好的整合在了一起,並明確分工,Electron負責硬體部分,“Chromium”和“Node.js”負責介面與邏輯,大家井井有條,共同構成了一個成本低廉卻十分高效的解決方案,在快速交付上甚至比Native還要快速。
Electron發展里程碑 ·      2013年4月11日,Electron以Atom Shell為名起步。 ·      2014年5月6日,Atom以及Atom Shell以MIT許可證開源。 ·      2015年4月17日,Atom Shell改名為Electron。 ·      2016年5月11日,1.0版本釋出。 ·      2016年5月20日,允許向Mac應用商店提交軟體包。 ·      2016年8月2日,支援Windows商店。

簡而言之,Electron JS是一個執行時框架,它允許使用者使用HTML5、CSS和JavaScript建立桌面套件應用程式,而大部分應用程式都是由兩種非常受歡迎的技術混合而成:Node.js和Chromium。因此,您編寫的任何Web應用程式都可以在Electron JS 上正常執行。
Electron的內建功能包括: ·      自動更新 - 使應用程式能夠自動更新、升級 ·      本機選單和通知 - 建立本機應用程式選單和上下文選單 ·      應用程式崩潰報告 - 您可以將崩潰報告提交給遠端伺服器 ·      除錯和分析 - Chromium的內容模組可以發現效能瓶頸和執行緩慢的原因。此外,您也可以在應用中使用自己喜歡的Chrome開發者工具 ·      Windows安裝程式 -您可以快速而簡單建立安裝包
二、Electron 可以用來做什麼?(哪些場景需要使用Electron) 以Windows平臺應用開發為例,大部分人首先會想到使用成熟的開發方案,如QT(C++)、WPF(C#) 等。但面臨以下幾種使用場景,這些方案將顯得捉襟見肘: ·      公司要設計一個全新的APP, 但技術人員大部分由前端開發構成 ·      公司原本就有線上的Web應用,但是想讓該應用能夠在桌面端直接開啟(離線狀態下也可使用),並增加一些與系統互動的功能   以我的親身經歷為例: 在SpreadJS專案中,我們需要將基於web版的表格編輯器封裝成APP使用,同時增加檔案操作的能力,如匯入匯出excel、匯入PDF等,而SpreadJS是一個純前端的表格控制元件,開發人員全部由前端開發組成,對C++和C#並不熟悉,如果投入過大的時間精力用來學習其他開發語言,整個專案的技術管理和專案管理將變得無法控制。除此之外,鑑於專案本身對應用的業務邏輯要求並不高,只是套一個具有瀏覽器屬性的執行環境即可,因此,單獨為此配置C++、C# 開發人員將無形中提升更多專案成本。
為此,我們引入了Electron框架:現有的前端開發人員能在不學習其他語言的情況下,直接搞定上述需求,這就是Electron 為我們帶來的價值。
三、為什麼選擇 Electron?(Electron的出現為前端開發者謀得了一份好差事) 可以這麼說,Electron這個框架讓網路里流傳很廣的一句話不再是玩笑:“不要和老夫說什麼C++、Java,老夫行走江湖就一把JS,遇到需求擼起袖子就是幹”。Electron可以幫助前端開發者在不需要學習其他語言和技能的情況下,快速開發跨平臺桌面應用。
Electron的出現將蠶食很大一部分桌面客戶端領域的市場份額,鑑於它的跨平臺特性,在不同系統之間僅需少量的優化工作。可想而知,這個成本到底有多低。 在開發的體驗上,Electron是基於"Chromium"和"Node.js"的,所以幾乎所有的Node.js模組都可以在Electron上執行,並很容易使用“npm”搭積木的方式快速交付一個產品。
四、大型應用使用Electron框架的成功案例  
1. SpreadJS純前端表格控制元件
 
SpreadJS 是一款基於 HTML5 的純前端電子表格控制元件,以“高速低耗、高度類似Excel、可無限擴充套件”為產品特色,提供移動跨平臺和瀏覽器支援,同時滿足 .NET、Java、App 等應用程式中的 Web Excel 元件開發、資料填報、線上文件、圖表公式聯動、類 Excel UI 設計等業務場景,在資料視覺化、Excel 匯入匯出、公式引用、資料繫結、框架整合等場景下無需大量程式碼開發和測試,極大降低了企業研發成本和專案交付風險。

2. WebTorrent WebTorrent,作為第一個在瀏覽器中執行的torrent客戶端,是一個完全由JavaScript編寫並使用WebRTC進行點對點傳輸的客戶端應用。無需任何外掛,擴充套件或安裝,WebTorrent將使用者連結到分散的瀏覽器到瀏覽器網路,以確保有效的檔案傳輸。 WebTorrent使用Electron框架開發,使其儘可能輕量、無廣告且開源。此外,使用Electron還有助於流式傳輸,並充當混合客戶端,將應用程式連線到所有流行BitTorrent和WebTorrent網路。
3. WordPress WordPress 桌面是一個使用了Electron和React作為框架的桌面應用程式,提供無縫的跨平臺體驗,允許使用者專注於他們的內容和設計,而不會被任何瀏覽器標籤所分心。
4. Slack Slack採用了Electron框架構建,鑑於其高效能表現和無框架外觀,將帶來與瀏覽器完全不同的體驗方式。對於尋求更集中的工作空間的團隊來說,Slack Desktop絕對是最適合的應用程式之一。 雖然Slack Desktop融合了很多技術,但大多數資原始檔和程式碼都是遠端載入的,它們結合了Chromium的渲染引擎和Node.js執行時和模組系統。
5. WhatsApp WhatsApp作為下載量最高的Messenger應用程式,也是基於Electron框架構建的。Electron幫助WhatsApp開發人員以低廉的成本完成了幾乎所有工作,並通過更加簡化和創新的技術,為使用者帶來全新的桌面體驗方式。
Electron 架構實現
 

Electron基本檔案結構 Electron有一個基本的檔案結構,類似於我們在建立網頁時使用的檔案結構: electron-quick-start - index.html 這是一個HTML5網頁,目的用於提供畫布(canvas) - main.js 建立視窗並處理系統事件 - package.json 是我們應用程式的啟動指令碼。它將在主程序中執行,幷包含有關應用程式的所有資訊 - render.js 處理應用程式的渲染過程
Electron的架構主要分為兩部分:主程序和渲染程序 回顧以往的web開發,我們的程式碼,無論是HTML、CSS還是Javascript,都是執行在瀏覽器沙盒中的,我們無法越過瀏覽器的許可權訪問系統本身的資源,程式碼的能力被限制在了瀏覽器中。瀏覽器之所以這麼做,是為了安全的考慮。設想一下,我們在使用瀏覽器的時候,會開啟各式各樣不同來源的網站,如果JavaScript程式碼有能力訪問並操作本地作業系統的資源,那將是多麼可怕的事情。
假設:你在某天不小心打開了一個惡意的網站,可能你儲存在硬碟上的檔案就被偷走了(都用不著去修電腦)。
但我們要開發的是桌面應用程式,如果無法訪問到本地的資源肯定是不行的。Electron將nodejs巧妙的融合了進來,讓nodejs作為整個程式的管家。管家擁有較高的許可權,可以訪問和操作本地資源,使用原本在瀏覽器中不提供的高階API。同時管家也管理著渲染程序視窗的建立和銷燬。所以,我們將這個管家稱之為主程序。在使用Electron開發的程式中,會使用main.js作為程式的主入口,該檔案內程式碼執行的內容,就是主程序中執行的內容。
主程序 主程序控制應用程式的生命週期。Electron 用來執行 package.json 的 main 指令碼的程序被稱為主程序。 在主程序中執行的指令碼通過建立web頁面來展示使用者介面。它內建了完整的Node.js API,主要用於開啟對話方塊以及建立渲染程序。此外,主程序還負責處理與其他作業系統互動、啟動和退出應用程式。
主程序就像是應用程式的管家,負責管理整個應用程式的生命週期以及所有渲染程序的建立。 按照慣例,主程序位於名為main.js的檔案中,你可以通過在package.json檔案中修改配置屬性來更改主程序檔案。 比如,我們可以開啟package.json並更改配置屬性:
“main”: “main.js”, =》“main”: “mainTest.js”,

 

請注意,Electron有且只有一個主程序。且主程序銷燬時,所有渲染程序也將一併銷燬。在chrome瀏覽器的預設策略下,每一個tab都是獨立的程序,Electron也正是利用了這一策略。
渲染程序 渲染程序是應用程式中的瀏覽器視窗。與主程序不同,Electron可以有許多渲染程序,且每個程序都是獨立的。由於 Electron 使用了 Chromium 來展示web 頁面,所以 Chromium 的多程序架構也被使用到。 每個Electron中的 web 頁面執行在它自己的渲染程序中。 正是因為每個渲染程序都是獨立的,因此一個崩潰不會影響另外一個,這些要歸功於Chromium的多程序架構。
如何保持程序通訊?   即便Electron中的所有程序同時存在並保持獨立執行,但他們仍然需要以某種方式進行溝通,尤其是在他們負責不同任務的時候。file:///C:/Users/markxu/AppData/Local/Temp/msohtmlclip1/01/clip_image034.png 為了保持程序通訊,Electron有一個程序間通訊系統(IPC也就是內部程序通訊)。您可以使用IPC在主程序和渲染程序之間傳遞資訊。
// 在主程序中
global.sharedObject = {
someProperty: 'default value'
}
// 在第一個頁面中
require('electron').remote.getGlobal('sharedObject').someProperty= 'new value'Copy
// 在第二個頁面中
console.log(require('electron').remote.getGlobal('sharedObject').someProperty)

 

Electron 程序通訊的實現方式: ·      主程序使用 BrowserWindow 例項建立頁面。每個 BrowserWindow 例項都在自己的渲染程序裡執行頁面。 當一個BrowserWindow 例項被銷燬後,相應的渲染程序也會被終止。 ·      主程序管理所有的web頁面和它們對應的渲染程序。 每個渲染程序都是獨立的,它只關心它所執行的 web頁面。 ·      在頁面中呼叫與 GUI 相關的原生 API 是不被允許的,因為在 web 頁面裡操作原生的GUI 資源是非常危險的,而且容易造成資源洩露。 如果你想在 web 頁面裡使用 GUI 操作,其對應的渲染程序必須與主程序進行通訊,請求主程序進行相關的 GUI 操作。 說句題外話:在兩個網頁(渲染程序)間共享資料最簡單的方法是使用瀏覽器中已經實現的 HTML5 API。 其中比較好的方案是用 Storage API, localStorage,sessionStorage 或者 IndexedDB,但這些不是今天的主題。   如何構建 Electron系統架構? 為了降低構建整個 Chromium 帶來的複雜度,Electron通過libchromiumcontent 來訪問 Chromium 的Content API。libchromiumcontent 是一個獨立的、引入了 Chromium Content 模組及其所有依賴的共享庫。使用者不需要一個強勁的機器來構建Electron。 Electron只用了Chromium的渲染庫而不是其全部元件。這使得升Chromium更加容易,但也意味著Electron缺少了Google Chrome裡的一些瀏覽器相關的特性。   打包 原來打包步驟略微繁瑣,如今由於社群發展,產生了很多優秀的打包工具,讓我們可以不用關注很多細節,(比如asar)
// 在主程序中
global.sharedObject = {
someProperty: 'default value'
}
// 在第一個頁面中
require('electron').remote.getGlobal('sharedObject').someProperty= 'new value'Copy
// 在第二個頁面中
console.log(require('electron').remote.getGlobal('sharedObject').someProperty)

 

main 端
ipcMain.on('readFile', (event, { filePath })=> {
content content = fs.readFileSync(filePath,'utf-8');
event.sender.send('readFileSuccess', { content});
});

  

renderer 端
ipcRenderer.on('readFileSuccess', (event, {content }) => {
console.log(`content: ${content}`);
});
ipcRender.send('readFile', {
filePath: '/path/to/file',
});

 

我們僅需做的 :將app 的目錄結構整理好,提供對應的資源,如icon等,然後使用工具製作映象即可將資源打包成為各個平臺下的APP應用。

 

打包工具的選擇 file:///C:/Users/markxu/AppData/Local/Temp/msohtmlclip1/01/clip_image036.jpg 通常情況下,我們選擇Electron-builder (跨平臺支援性較好,上手成本低)  

Electron 快速上手實踐  

這裡我準備了一個Demo專案,這個Demo原始碼您可以在葡萄城技術社群獲取到。

這個演示我將以SpreadJS的一個應用為例,展示如何將Web應用轉換為Electron桌面應用。

我這裡使用electron-builder進行專案檔案的打包,您可以直接在專案根目錄通過 npx electron-builder命令執行打包命令。

專案打包過程可能需要些時間,在這期間,我向您介紹一下Electron 打包的配置檔案,您可以根據您的實際情況配置如下檔案以滿足您的需求

"build": {
"appId": "your.id", // appid
"productName": "程式名稱",// 程式名稱
"files": [ // 打包需要的不過濾的檔案
"build/**/*",
"main.js",
"node_modules/**/*"
],
"directories": {
"output": "./dist-out", // 打包輸出的目錄
"app": "./", // package所在路徑
"buildResources": "assets"
},
"nsis": {
"oneClick": false, // 是否需要點選安裝,自動更新需要關掉
"allowToChangeInstallationDirectory":true, //是否能夠選擇安裝路徑
"perMachine": true // 是否需要輔助安裝頁面
},
"win": {
"target": [
{
"target": "nsis", // 輸出目錄的方式
"arch": [ // 輸出的配置ia32或者x64/x86
"x64"
}
],
"publish": [ // 自動更新的配置
{
"provider": "generic", // 自己配置更新的伺服器要選generic
"url":"http://127.0.0.1:8080/updata/" //更新配置的路徑
}
}
}  

 

 緩慢的打包程序結束後,您應該可以在專案目錄中的build目錄看到生成的exe檔案

點選安裝,它就像一個普通的桌面應用程式一樣開始了安裝程序。(這裡的軟體名稱和軟體logo都是我們專案中配置好的)

 

安裝完成後,開啟程式,這裡我們可以看到打包好的應用和在Web端訪問時的效果別無二致,同時也能夠像其他桌面應用程式一樣,支援離線使用。

 

 

至此,初探Electron,從入門到實踐教程結束,如果大家還有更多使用上的疑惑或想要了解更多高階用法,可以通過官方文件學習https://electronjs.org/docs。

同時,葡萄城資深開發工程師也為大家在2019年9月4日 14:00準備了乾貨滿滿的線上技術分享公開課,本次分享的內容也正是文中提到的Electron實踐,屆時歡迎大家按時參加。

http://live.vhall.com/878864086