您好,登錄后才能下訂單哦!
本文由葡萄城技術(shù)團(tuán)隊于博客園原創(chuàng)并首發(fā)
轉(zhuǎn)載請注明出處:葡萄城官網(wǎng),葡萄城為開發(fā)者提供專業(yè)的開發(fā)工具、解決方案和服務(wù),賦能開發(fā)者。
?
在開始之前,我想您一定會有這樣的困惑:標(biāo)題里的Electron 是什么?Electron能做什么?許多偉大的公司使用Electron框架的原因又是什么?
帶著這些問題和疑惑,通過本文的介紹,可助您全面地認(rèn)識Electron這門新興的技術(shù),迅速找到其入門途徑,并理解Electron為何被稱為當(dāng)下開發(fā)桌面App的最佳選擇。
?
初探Electron
一、Electron是什么?(為何稱之為“跨平臺桌面瀏覽器”)
前端開發(fā)的魅力,在于開發(fā)者隨時要面臨全新技術(shù)的挑戰(zhàn)!
曾幾何時,作為前端開發(fā)者的你可曾想過:如何利用HTML、CSS和JavaScript構(gòu)建跨平臺的桌面應(yīng)用程序?借助 Electron,這項工作將比你想象的更加簡單。
Electron作為一個使用新興技術(shù)(包括JavaScript,HTML和CSS)創(chuàng)建桌面應(yīng)用程序的框架,其負(fù)責(zé)處理硬件,開發(fā)者可以更專注于應(yīng)用程序的核心并從底層更改其設(shè)計。
Electron設(shè)計之初便充分結(jié)合了當(dāng)今最好的Web技術(shù),作為一個跨平臺的“集成框架”,它可以輕松地與Mac、Windows和Linux兼容。而所謂的“集成框架”也就是它將“Chromium”和“Node.js”很好的集成在了一起,并明確分工,Electron負(fù)責(zé)硬件部分,“Chromium”和“Node.js”負(fù)責(zé)界面與邏輯,大家井井有條,共同構(gòu)成了一個成本低廉卻十分高效的解決方案,在快速交付上甚至比Native還要快速。
Electron發(fā)展里程碑
·? ?? ?2013年4月11日,Electron以Atom Shell為名起步。
·? ?? ?2014年5月6日,Atom以及Atom Shell以MIT許可證開源。
·? ?? ?2015年4月17日,Atom Shell改名為Electron。
·? ?? ?2016年5月11日,1.0版本發(fā)布。
·? ?? ?2016年5月20日,允許向Mac應(yīng)用商店提交軟件包。
·? ?? ?2016年8月2日,支持Windows商店。
簡而言之,Electron JS是一個運行時框架,它允許用戶使用HTML5、CSS和JavaScript創(chuàng)建桌面套件應(yīng)用程序,而大部分應(yīng)用程序都是由兩種非常受歡迎的技術(shù)混合而成:Node.js和Chromium。因此,您編寫的任何Web應(yīng)用程序都可以在Electron JS 上正常運行。
Electron的內(nèi)置功能包括:
·? ?? ?自動更新 - 使應(yīng)用程序能夠自動更新、升級
·? ?? ?本機(jī)菜單和通知 - 創(chuàng)建本機(jī)應(yīng)用程序菜單和上下文菜單
·? ?? ?應(yīng)用程序崩潰報告 - 您可以將崩潰報告提交給遠(yuǎn)程服務(wù)器
·? ?? ?調(diào)試和分析 - Chromium的內(nèi)容模塊可以發(fā)現(xiàn)性能瓶頸和運行緩慢的原因。此外,您也可以在應(yīng)用中使用自己喜歡的Chrome開發(fā)者工具
·? ?? ?Windows安裝程序 -您可以快速而簡單創(chuàng)建安裝包
二、Electron 可以用來做什么?(哪些場景需要使用Electron)
以Windows平臺應(yīng)用開發(fā)為例,大部分人首先會想到使用成熟的開發(fā)方案,如QT(C++)、WPF(C#) 等。但面臨以下幾種使用場景,這些方案將顯得捉襟見肘:
·? ?? ?公司要設(shè)計一個全新的APP, 但技術(shù)人員大部分由前端開發(fā)構(gòu)成
·? ?? ?公司原本就有在線的Web應(yīng)用,但是想讓該應(yīng)用能夠在桌面端直接打開(離線狀態(tài)下也可使用),并增加一些與系統(tǒng)交互的功能
?
以我的親身經(jīng)歷為例:
在SpreadJS項目中,我們需要將基于web版的表格編輯器封裝成APP使用,同時增加文件操作的能力,如導(dǎo)入導(dǎo)出excel、導(dǎo)入PDF等,而SpreadJS是一個純前端的表格控件,開發(fā)人員全部由前端開發(fā)組成,對C++和C#并不熟悉,如果投入過大的時間精力用來學(xué)習(xí)其他開發(fā)語言,整個項目的技術(shù)管理和項目管理將變得無法控制。除此之外,鑒于項目本身對應(yīng)用的業(yè)務(wù)邏輯要求并不高,只是套一個具有瀏覽器屬性的運行環(huán)境即可,因此,單獨為此配置C++、C# 開發(fā)人員將無形中提升更多項目成本。
為此,我們引入了Electron框架:現(xiàn)有的前端開發(fā)人員能在不學(xué)習(xí)其他語言的情況下,直接搞定上述需求,這就是Electron 為我們帶來的價值。
三、為什么選擇 Electron?(Electron的出現(xiàn)為前端開發(fā)者謀得了一份好差事)
可以這么說,Electron這個框架讓網(wǎng)路里流傳很廣的一句話不再是玩笑:“不要和老夫說什么C++、Java,老夫行走江湖就一把JS,遇到需求擼起袖子就是干”。Electron可以幫助前端開發(fā)者在不需要學(xué)習(xí)其他語言和技能的情況下,快速開發(fā)跨平臺桌面應(yīng)用。
Electron的出現(xiàn)將蠶食很大一部分桌面客戶端領(lǐng)域的市場份額,鑒于它的跨平臺特性,在不同系統(tǒng)之間僅需少量的優(yōu)化工作??上攵?,這個成本到底有多低。
在開發(fā)的體驗上,Electron是基于"Chromium"和"Node.js"的,所以幾乎所有的Node.js模塊都可以在Electron上運行,并很容易使用“npm”搭積木的方式快速交付一個產(chǎn)品。
四、大型應(yīng)用使用Electron框架的成功案例
?
1. SpreadJS純前端表格控件
?
SpreadJS?是一款基于 HTML5 的純前端電子表格控件,以“高速低耗、高度類似Excel、可無限擴(kuò)展”為產(chǎn)品特色,提供移動跨平臺和瀏覽器支持,同時滿足 .NET、Java、App 等應(yīng)用程序中的 Web Excel 組件開發(fā)、數(shù)據(jù)填報、在線文檔、圖表公式聯(lián)動、類 Excel UI 設(shè)計等業(yè)務(wù)場景,在數(shù)據(jù)可視化、Excel 導(dǎo)入導(dǎo)出、公式引用、數(shù)據(jù)綁定、框架集成等場景下無需大量代碼開發(fā)和測試,極大降低了企業(yè)研發(fā)成本和項目交付風(fēng)險。
2. WebTorrent
WebTorrent,作為第一個在瀏覽器中運行的torrent客戶端,是一個完全由JavaScript編寫并使用WebRTC進(jìn)行點對點傳輸?shù)目蛻舳藨?yīng)用。無需任何插件,擴(kuò)展或安裝,WebTorrent將用戶鏈接到分散的瀏覽器到瀏覽器網(wǎng)絡(luò),以確保有效的文件傳輸。
WebTorrent使用Electron框架開發(fā),使其盡可能輕量、無廣告且開源。此外,使用Electron還有助于流式傳輸,并充當(dāng)混合客戶端,將應(yīng)用程序連接到所有流行BitTorrent和WebTorrent網(wǎng)絡(luò)。
3. WordPress
WordPress 桌面是一個使用了Electron和React作為框架的桌面應(yīng)用程序,提供無縫的跨平臺體驗,允許用戶專注于他們的內(nèi)容和設(shè)計,而不會被任何瀏覽器標(biāo)簽所分心。
4. Slack
Slack采用了Electron框架構(gòu)建,鑒于其高性能表現(xiàn)和無框架外觀,將帶來與瀏覽器完全不同的體驗方式。對于尋求更集中的工作空間的團(tuán)隊來說,Slack Desktop絕對是最適合的應(yīng)用程序之一。
雖然Slack Desktop融合了很多技術(shù),但大多數(shù)資源文件和代碼都是遠(yuǎn)程加載的,它們結(jié)合了Chromium的渲染引擎和Node.js運行時和模塊系統(tǒng)。
5. WhatsApp
WhatsApp作為下載量最高的Messenger應(yīng)用程序,也是基于Electron框架構(gòu)建的。Electron幫助WhatsApp開發(fā)人員以低廉的成本完成了幾乎所有工作,并通過更加簡化和創(chuàng)新的技術(shù),為用戶帶來全新的桌面體驗方式。
Electron 架構(gòu)實現(xiàn)
?
Electron基本文件結(jié)構(gòu)
Electron有一個基本的文件結(jié)構(gòu),類似于我們在創(chuàng)建網(wǎng)頁時使用的文件結(jié)構(gòu):
electron-quick-start
- index.html 這是一個HTML5網(wǎng)頁,目的用于提供畫布(canvas)
- main.js 創(chuàng)建窗口并處理系統(tǒng)事件
- package.json 是我們應(yīng)用程序的啟動腳本。它將在主進(jìn)程中運行,并包含有關(guān)應(yīng)用程序的所有信息
- render.js 處理應(yīng)用程序的渲染過程
Electron的架構(gòu)主要分為兩部分:主進(jìn)程和渲染進(jìn)程
回顧以往的web開發(fā),我們的代碼,無論是HTML、CSS還是Javascript,都是運行在瀏覽器沙盒中的,我們無法越過瀏覽器的權(quán)限訪問系統(tǒng)本身的資源,代碼的能力被限制在了瀏覽器中。瀏覽器之所以這么做,是為了安全的考慮。設(shè)想一下,我們在使用瀏覽器的時候,會打開各式各樣不同來源的網(wǎng)站,如果JavaScript代碼有能力訪問并操作本地操作系統(tǒng)的資源,那將是多么可怕的事情。
假設(shè):你在某天不小心打開了一個惡意的網(wǎng)站,可能你存儲在硬盤上的文件就被偷走了(都用不著去修電腦)。
但我們要開發(fā)的是桌面應(yīng)用程序,如果無法訪問到本地的資源肯定是不行的。Electron將nodejs巧妙的融合了進(jìn)來,讓nodejs作為整個程序的管家。管家擁有較高的權(quán)限,可以訪問和操作本地資源,使用原本在瀏覽器中不提供的高級API。同時管家也管理著渲染進(jìn)程窗口的創(chuàng)建和銷毀。所以,我們將這個管家稱之為主進(jìn)程。在使用Electron開發(fā)的程序中,會使用main.js作為程序的主入口,該文件內(nèi)代碼執(zhí)行的內(nèi)容,就是主進(jìn)程中執(zhí)行的內(nèi)容。
主進(jìn)程
主進(jìn)程控制應(yīng)用程序的生命周期。Electron 用來運行 package.json 的 main 腳本的進(jìn)程被稱為主進(jìn)程。 在主進(jìn)程中運行的腳本通過創(chuàng)建web頁面來展示用戶界面。它內(nèi)置了完整的Node.js API,主要用于打開對話框以及創(chuàng)建渲染進(jìn)程。此外,主進(jìn)程還負(fù)責(zé)處理與其他操作系統(tǒng)交互、啟動和退出應(yīng)用程序。
主進(jìn)程就像是應(yīng)用程序的管家,負(fù)責(zé)管理整個應(yīng)用程序的生命周期以及所有渲染進(jìn)程的創(chuàng)建。
按照慣例,主進(jìn)程位于名為main.js的文件中,你可以通過在package.json文件中修改配置屬性來更改主進(jìn)程文件。
比如,我們可以打開package.json并更改配置屬性:
1 | “main”: “main.js”, =》“main”: “mainTest.js”, |
?
請注意,Electron有且只有一個主進(jìn)程。且主進(jìn)程銷毀時,所有渲染進(jìn)程也將一并銷毀。在chrome瀏覽器的默認(rèn)策略下,每一個tab都是獨立的進(jìn)程,Electron也正是利用了這一策略。
渲染進(jìn)程
渲染進(jìn)程是應(yīng)用程序中的瀏覽器窗口。與主進(jìn)程不同,Electron可以有許多渲染進(jìn)程,且每個進(jìn)程都是獨立的。由于 Electron 使用了 Chromium 來展示web 頁面,所以 Chromium 的多進(jìn)程架構(gòu)也被使用到。 每個Electron中的 web 頁面運行在它自己的渲染進(jìn)程中。
正是因為每個渲染進(jìn)程都是獨立的,因此一個崩潰不會影響另外一個,這些要歸功于Chromium的多進(jìn)程架構(gòu)。
如何保持進(jìn)程通信?
?
即便Electron中的所有進(jìn)程同時存在并保持獨立運行,但他們?nèi)匀恍枰阅撤N方式進(jìn)行溝通,尤其是在他們負(fù)責(zé)不同任務(wù)的時候。file:///C:/Users/markxu/AppData/Local/Temp/msohtmlclip1/01/clip_image034.png
為了保持進(jìn)程通信,Electron有一個進(jìn)程間通信系統(tǒng)(IPC也就是內(nèi)部進(jìn)程通信)。您可以使用IPC在主進(jìn)程和渲染進(jìn)程之間傳遞信息。
1 2 3 4 5 6 7 8 | // 在主進(jìn)程中 global.sharedObject = { someProperty:? 'default value' } // 在第一個頁面中 require( 'electron' ).remote.getGlobal( 'sharedObject' ).someProperty=? 'new value' Copy // 在第二個頁面中 console.log(require( 'electron' ).remote.getGlobal( 'sharedObject' ).someProperty) |
?
Electron 進(jìn)程通信的實現(xiàn)方式:
·? ?? ?主進(jìn)程使用 BrowserWindow 實例創(chuàng)建頁面。每個 BrowserWindow 實例都在自己的渲染進(jìn)程里運行頁面。 當(dāng)一個BrowserWindow 實例被銷毀后,相應(yīng)的渲染進(jìn)程也會被終止。
·? ?? ?主進(jìn)程管理所有的web頁面和它們對應(yīng)的渲染進(jìn)程。 每個渲染進(jìn)程都是獨立的,它只關(guān)心它所運行的 web頁面。
·? ?? ?在頁面中調(diào)用與 GUI 相關(guān)的原生 API 是不被允許的,因為在 web 頁面里操作原生的GUI 資源是非常危險的,而且容易造成資源泄露。 如果你想在 web 頁面里使用 GUI 操作,其對應(yīng)的渲染進(jìn)程必須與主進(jìn)程進(jìn)行通訊,請求主進(jìn)程進(jìn)行相關(guān)的 GUI 操作。
說句題外話:在兩個網(wǎng)頁(渲染進(jìn)程)間共享數(shù)據(jù)最簡單的方法是使用瀏覽器中已經(jīng)實現(xiàn)的 HTML5 API。 其中比較好的方案是用 Storage API, localStorage,sessionStorage 或者 IndexedDB,但這些不是今天的主題。
?
如何構(gòu)建 Electron系統(tǒng)架構(gòu)?
為了降低構(gòu)建整個 Chromium 帶來的復(fù)雜度,Electron通過libchromiumcontent 來訪問 Chromium 的Content API。libchromiumcontent 是一個獨立的、引入了 Chromium Content 模塊及其所有依賴的共享庫。用戶不需要一個強(qiáng)勁的機(jī)器來構(gòu)建Electron。
Electron只用了Chromium的渲染庫而不是其全部組件。這使得升Chromium更加容易,但也意味著Electron缺少了Google Chrome里的一些瀏覽器相關(guān)的特性。
?
打包
原來打包步驟略微繁瑣,如今由于社區(qū)發(fā)展,產(chǎn)生了很多優(yōu)秀的打包工具,讓我們可以不用關(guān)注很多細(xì)節(jié),(比如asar)
1 2 3 4 5 6 7 8 | // 在主進(jìn)程中 global.sharedObject = { someProperty:? 'default value' } // 在第一個頁面中 require( 'electron' ).remote.getGlobal( 'sharedObject' ).someProperty=? 'new value' Copy // 在第二個頁面中 console.log(require( 'electron' ).remote.getGlobal( 'sharedObject' ).someProperty) |
?
main 端
1 2 3 4 | ipcMain.on( 'readFile' , (event, { filePath })=> { content content = fs.readFileSync(filePath, 'utf-8' ); event.sender.send( 'readFileSuccess' , { content}); }); |
renderer 端
1 2 3 4 5 6 | ipcRenderer.on( 'readFileSuccess' , (event, {content }) => { console.log(`content: ${content}`); }); ipcRender.send( 'readFile' , { filePath:? '/path/to/file' , }); |
?
我們僅需做的 :將app 的目錄結(jié)構(gòu)整理好,提供對應(yīng)的資源,如icon等,然后使用工具制作鏡像即可將資源打包成為各個平臺下的APP應(yīng)用。
?
打包工具的選擇
file:///C:/Users/markxu/AppData/Local/Temp/msohtmlclip1/01/clip_image036.jpg
通常情況下,我們選擇Electron-builder (跨平臺支持性較好,上手成本低)
?
Electron 快速上手實踐
這里我準(zhǔn)備了一個Demo項目,這個Demo源碼您可以在葡萄城技術(shù)社區(qū)獲取到。
這個演示我將以SpreadJS的一個應(yīng)用為例,展示如何將Web應(yīng)用轉(zhuǎn)換為Electron桌面應(yīng)用。
我這里使用electron-builder進(jìn)行項目文件的打包,您可以直接在項目根目錄通過 npx electron-builder命令執(zhí)行打包命令。
項目打包過程可能需要些時間,在這期間,我向您介紹一下Electron 打包的配置文件,您可以根據(jù)您的實際情況配置如下文件以滿足您的需求
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | "build" : { "appId" :? "your.id" ,? // appid "productName" :? "程序名稱" , // 程序名稱 "files" : [? // 打包需要的不過濾的文件 "build/**/*" , "main.js" , "node_modules/**/*" ], "directories" : { "output" :? "./dist-out" ,? // 打包輸出的目錄 "app" :? "./" ,? // package所在路徑 "buildResources" :? "assets" }, "nsis" : { "oneClick" :? false ,? // 是否需要點擊安裝,自動更新需要關(guān)掉 "allowToChangeInstallationDirectory" : true ,? //是否能夠選擇安裝路徑 "perMachine" :? true ?// 是否需要輔助安裝頁面 }, "win" : { "target" : [ { "target" :? "nsis" ,? // 輸出目錄的方式 "arch" : [? // 輸出的配置ia32或者x64/x86 "x64" } ], "publish" : [? // 自動更新的配置 { "provider" :? "generic" ,? // 自己配置更新的服務(wù)器要選generic "url" : "http://127.0.0.1:8080/updata/" ?//更新配置的路徑 } } } |
?
?緩慢的打包進(jìn)程結(jié)束后,您應(yīng)該可以在項目目錄中的build目錄看到生成的exe文件
點擊安裝,它就像一個普通的桌面應(yīng)用程序一樣開始了安裝進(jìn)程。(這里的軟件名稱和軟件logo都是我們項目中配置好的)
?
安裝完成后,打開程序,這里我們可以看到打包好的應(yīng)用和在Web端訪問時的效果別無二致,同時也能夠像其他桌面應(yīng)用程序一樣,支持離線使用。
?
?
至此,初探Electron,從入門到實踐教程結(jié)束,如果大家還有更多使用上的疑惑或想要了解更多高級用法,可以通過官方文檔學(xué)習(xí)https://electronjs.org/docs。
同時,葡萄城資深開發(fā)工程師也為大家在2019年9月4日 14:00準(zhǔn)備了干貨滿滿的線上技術(shù)分享公開課,本次分享的內(nèi)容也正是文中提到的Electron實踐,屆時歡迎大家按時參加。
http://live.vhall.com/878864086
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。