本文引用了作者“ ConardLi”的《用JS開發跨平臺桌面應用,從原理到實踐》一文部分內容,原文鏈接:segmentfault.com/a/1190000019426512,感謝原作者的無私分享。
1、引言
現在開發IM應用動不動就要求多端——即Android端、iOS端、PC端、Web端等,Android端和iOS端作為兩種不同的移動端技術,單獨開發和維護還能理解,PC端和Web端如果要單獨開發那就有點頭大了,必竟開發傳統的PC桌面應用成本太高(QT這類技術跟Web技術相比,上手難度大的多,而且太小眾)。所以,很大情況下大家都是PC富客戶端和Web端二選一,對于比較磨嘰的老板、產品經理或客戶來說,這是個很費口舌的事情(你懂的。。。)。
在即時通訊網的官方技術群里不只一次看到大家在討論Electron技術,作為新一代基于Web的桌面技術,已經被越來越的產品采用,成熟度和認可度都不錯,Electron技術可以降低開發PC端的成本和難度,或許PC富客戶端和Web端再也不需要二選一了。
本文將從入門者的角度,為你快速講解Electron到底是個什么技術,包括案例介紹、技術優勢、技術體驗、實現原理等。
(本文同步發布于:http://www.52im.net/thread-2616-1-1.html)
2、傳統桌面應用程序
桌面應用程序,又稱為 GUI 程序(Graphical User Interface),但是和 GUI 程序也有一些區別。桌面應用程序 將 GUI 程序從GUI 具體為“桌面”,使冷冰冰的像塊木頭一樣的電腦概念更具有 人性化,更生動和富有活力。
我們電腦上使用的各種客戶端程序都屬于桌面應用程序,近年來WEB和移動端的興起讓桌面程序漸漸暗淡,但是在某些日常功能或者行業應用中桌面應用程序仍然是必不可少的。
傳統的桌面應用開發方式,一般是下面兩種。
1)原生開發:
直接將語言編譯成可執行文件,直接調用系統API,完成UI繪制等。這類開發技術,有著較高的運行效率,但一般來說,開發速度較慢,技術要求較高,例如:
a. 使用C++ / MFC開發Windows應用;
b. 使用Objective-C開發MAC應用。
2)托管平臺:
一開始就有本地開發和UI開發。一次編譯后,得到中間文件,通過平臺或虛機完成二次加載編譯或解釋運行。運行效率低于原生編譯,但平臺優化后,其效率也是比較可觀的。就開發速度方面,比原生編譯技術要快一些。例如:
a. 使用C# / .NET Framework(只能開發Windows應用);
b. Java / Swing。
不過,上面兩種對前端開發人員太不友好了,基本是前端人員不會涉及的領域,但是在這個"大前端"的時代,前端開發者正在想方設法涉足各個領域,使用WEB技術開發客戶端的方式橫空出世——這就是本文正在介紹的“Electron”技術。
3、什么是Electron技術?
Electron是由Github開發,用HTML,CSS和JavaScript來構建跨平臺桌面應用程序的一個開源庫。 Electron通過將Chromium和Node.js合并到同一個運行時環境中,并將其打包為Mac,Windows和Linux系統下的應用來實現這一目的。通過Node它提供了通常瀏覽器所不能提供的能力。
Electron于2013年作為構建Github上可編程的文本編輯器Atom的框架而被開發出來(PS:據說這個Atom看起來很漂亮,但很難用...)。這兩個項目在2014春季開源。
其實,Electron在早期一直是由原作者 Cheng Zhao 一個人維護和開發的(他現在是 Github 北京 Atom 編輯器開發 team 的一名工程師)。在這之前,Zhao主要進行node-webkit(現在叫nw.js)的開發工作。從概念上,Electron與nw.js很相似,但是他們有很重要的區別:一個主要的不同點是Electron 通過 Googles Chromium Content Module 來使用 Chromium 的功能,nw.js 則直接使用了 Chromium本身。
PS:Electron的作者 Cheng Zhao 應該是個中國人,但網上能查到的信息非常少,連中文名都沒有(大佬就是低調...),這個框架作者還為一本中文譯名叫《跨平臺桌面應用開發:基于Electron與NW.js》的書寫了序(見下圖)。
Electron 發展歷程中的里程碑:
目前它已成為開源開發者、初創企業和老牌公司常用的開發工具(看看誰在使用Electron)。
Electron資源:
1)Electron官網:https://electronjs.org;
2)Electron Github:https://github.com/electron;
3)Electron開發手冊:https://electronjs.org/docs。
4、Electron為何如此迷人?
可能主要是因為,猿類里的亞種——“前端開發”,又有了新的出路了吧,已經在崗的前端也有了新一年的 KPI/OKR,剛起步的創業公司可以只拉一個前端就能開發跨平臺的多個桌面客戶端... ...(開個玩笑)。
1)可以用 Web 前端技術開發跨平臺的桌面客戶端:
這是 Electron 最迷人的地方,究其根本是因為它是建立在 Chromium 和 NodeJS 之上的,一個負責界面,一個負責背后的邏輯,典型的"你負責貌美如花,我負責賺錢養家",為什么 Electron 能夠開發跨平臺的桌面應用也就可以理解了。
而對于前端開發來說,“不要和老夫說什么 C++,Java,老夫行走江湖就一把 JS,遇到需求就是干”。前端開發可以用自己熟悉的方式去寫應用界面,邏輯部分也還是 JS,如果你精通 Node 后端,那后端也可以插一腳,“鳥槍換大炮”,你開發客戶端的能力有一種“忽如一夜春風來”的感覺。
但是,不同系統間還是會有很大的不同,“同一套代碼,編譯出跨平臺的多個客戶端”,話是這么說,但你得因為系統的不同做一些額外的處理,以使得打包出的不同系統下的應用都可以正常工作,這可能是一些“if - else”的成本,但相比于那80%都能完全復用的代碼,這些成本已經很小了。
綜上所述:一個 Web 前端開發者可以花很少的成本去上手 Electron,而相比于以前開發多平臺客戶端的成本,利用 Electron 開發多平臺客戶端的成本是極低的。
2)可以從 NodeJS 的生態獲得極大的助力:
因為 Electron 是基于 NodeJS 的,意味著,NodeJS 這個大生態下的模塊,Electron 也都可以用,這減少了很多造輪子的時間,你要寫一些邏輯將首先思考有沒有成熟的模塊可以引入,而不是自己吭哧吭哧閉門造車,自己造時間精力會大量得被消耗,上路還可能翻車。
Electron 從 NodeJS 獲益有2個方面,一個方面是如現代的 web 項目一般,開發構建流程可以引入很多成熟的包去打造出適合自己項目的開發工作流,另一個方面就是其應用本身也可以依賴需要的包去完成自己的功能。
3)“這個東西做Web版就可以,干嗎還要開發PC客戶端版?”
既然 Electron 是用 Web 技術寫客戶端,那么看上去 Electron 要做的事,可以搬到網站上。
為什么還要搬到PC客戶端,這里有3個角度的回答:
a. 用戶角度: 客戶端是一款獨立的軟件,其綜合體驗一般都是比網站高的,尤其是涉及到「工具」范疇的應用,此外,特定的用戶群體也會有類似的使用習慣;
b. 發行方角度: 客戶端是另一種產品形式,是一種產品的分發方式和入口,客戶端可以實現很多本地應用獨有的需求去觸達用戶,也能提供更加可靠的服務;
c. 開發角度: 終于...不用考慮瀏覽器兼容了,Chromium 也足夠開發使用一些先進的 CSS 或 JS 特性,我們現在還沒計劃引入 webpack 和 babel,因為現在好像夠用,克制才是愛,除了寫起來爽,對于開發來說,終于跳出了瀏覽器的沙盒,你可以自己去控制 Electron 中的“瀏覽器”,莫名的開心。
這些綜合起來回答這個小節的問題就是,用 Electron 開發客戶端,用戶體驗好,開發麻煩小,功能更強大,老板脫發少。
4)那在 Electron 和 NW.js 之間,為啥選擇前者?
我沒怎么用過 NW.js,但當時在沒有時間深入體驗的實際情況下,我選擇生態好的。
Electron 相關的社區生態很好,之后的開發過程也證明了這一點,遇到的問題基本都能通過 Stackoverflow 找到,如果沒有找到,新開一個問題或者去 Github 提 Issue 都可以得到較快的解決,除非是一些已知的問題或一些看文檔可以解決的問題,這類問題可能會被忽略過去。
所以,生態更好一些,我選擇了 Electron。
5)總結一下,使用Electron開發的理由:
a. 使用具有強大生態的Web技術進行開發,開發成本低,可擴展性強,更炫酷的UI;
b. 跨平臺,一套代碼可打包為Windows、Linux、Mac三套軟件,且編譯快速;
c. 可直接在現有Web應用上進行擴展,提供瀏覽器不具備的能力;
d. 你是一個前端????~
當然,我們也要認清它的缺點:性能比原生桌面應用要低,最終打包后的應用比原生應用大很多。
5、Electron的開發體驗
兼容性:雖然你還在用WEB技術進行開發,但是你不用再考慮兼容性問題了,你只需要關心你當前使用Electron的版本對應Chrome的版本,一般情況下它已經足夠新來讓你使用最新的API和語法了,你還可以手動升級Chrome版本。同樣的,你也不用考慮不同瀏覽器帶的樣式和代碼兼容問題。
NodeJS環境:這可能是很多前端開發者曾經夢想過的功能,在WEB界面中使用Node.js提供的強大API,這意味著你在WEB頁面直接可以操作文件,調用系統API,甚至操作數據庫。當然,除了完整的 Node API,你還可以使用額外的幾十萬個npm模塊。
跨域:你可以直接使用Node提供的request模塊進行網絡請求,這意味著你無需再被跨域所困擾。
強大的擴展性:借助node-ffi,為應用程序提供強大的擴展性(更詳細的介紹可以自行百度相關資料了解一下)。
6、那么,都有誰在用 Electron?
現在市面上已經有非常多的應用在使用Electron進行開發了,包括我們熟悉的VS Code客戶端、GitHub客戶端、Atom客戶端等等。
印象很深的,去年迅雷在發布迅雷X10.1時的文案:
從迅雷X 10.1版本開始,我們采用Electron軟件框架完全重寫了迅雷主界面。使用新框架的迅雷X可以完美支持2K、4K等高清顯示屏,界面中的文字渲染也更加清晰銳利。從技術層面來說,新框架的界面繪制、事件處理等方面比老框架更加靈活高效,因此界面的流暢度也顯著優于老框架的迅雷。至于具體提升有多大?您一試便知。
你可以打開VS Code,點擊“幫助”-“切換開發人員工具”,來調試VS Code客戶端的界面:
Electron的官網還列舉了更多案例:看看誰在使用Electron。
7、Electron的運行原理
如上圖所示,Electron 結合了 Chromium、Node.js 和用于調用操作系統本地功能的API。
1)Chromium:
Chromium 是 Google 為發展 Chrome 瀏覽器而啟動的開源項目,Chromium 相當于 Chrome 的工程版或稱實驗版,新功能會率先在 Chromium 上實現,待驗證后才會應用在Chrome 上,故 Chrome 的功能會相對落后但較穩定。
Chromium為Electron提供強大的UI能力,可以在不考慮兼容性的情況下開發界面。
2)Node.js:
Node.js是一個讓 JavaScript 運行在服務端的開發平臺,Node 使用事件驅動,非阻塞I/O 模型而得以輕量和高效。
單單靠Chromium是不能具備直接操作原生GUI能力的,Electron內集成了Nodejs,這讓其在開發界面的同時也有了操作系統底層 API 的能力,Nodejs 中常用的 Path、fs、Crypto 等模塊在 Electron 可以直接使用。
3)系統API:
為了提供原生系統的GUI支持,Electron內置了原生應用程序接口,對調用一些系統功能,如調用系統通知、打開系統文件夾提供支持。
在開發模式上,Electron在調用系統API和繪制界面上是分離開發的,下面我們來看看Electron關于進程如何劃分。
8、Electron項目和Web項目的區別
Electron核心可以分成2個部分:主進程和渲染進程。
主進程連接著操作系統和渲染進程,可以把她看做頁面和計算機溝通的橋梁。渲染進程就是我們所熟悉前端環境了,只是載體改變了,從瀏覽器變成了window。
傳統的Web環境我們是不能對用戶的系統就行操作的,而Electron相當于NodeJS環境,我們可以在項目里使用所有的node api(Electron的作者相當機智...)。
簡單理解:給Web項目套上一個NodeJS環境的殼,就是Electron技術。
項目結構:相比web項目,桌面項目多了一個進程,如下圖所示。
項目遷移:如果要遷移項目到Web端,就需要把項目中的Electron提供的API和NodeJS的API完全剝離出來,只能遺留Web的代碼,比如 node fs模塊,Electron提供ipc 模塊,都需要剝離。如果你一開始就打算雙端程序,在開始寫代碼時應該對Web代碼和Elecctron的代碼進行分離,以便后期的遷移。
9、本文小結
Electron是一個年輕的開源項目,被原作者一個人維護了很長時間,這反而成了很好的開始。瀏覽器是個比較復雜的東西,很少能引起人的興趣,但是Electron已經有了很多個開發者,還有很好的跨平臺支持,有了個不錯的開始。
最后說一些可以幫助你更好學習electron的基礎知識:
1)Webpack: 最強構建工具,沒有之一,了解webpack,你才能更好編寫項目配置;
2)NodeJS: Electron是搭載谷歌v8內核的高性能的NodeJS環境 ,所有NodeJS能用的東西,我們都能用。是不是很酸爽?
附錄:有關Web即時通訊技術的文章
Web即時通訊新手入門貼:
《新手入門貼:詳解Web端即時通訊技術的原理》
Web端即時通訊技術盤點請參見:
《Web端即時通訊技術盤點:短輪詢、Comet、Websocket、SSE》
關于Ajax短輪詢:
找這方面的資料沒什么意義,除非忽悠客戶,否則請考慮其它3種方案即可。
有關Comet技術的詳細介紹請參見:
更多WebSocket的詳細介紹請參見:
有關SSE的詳細介紹文章請參見:
《SSE技術詳解:一種全新的HTML5服務器推送事件技術》
更多WEB即時通訊文章請見:
http://www.52im.net/forum.php?mod=collection&action=view&ctid=15
(本文同步發布于:http://www.52im.net/thread-2616-1-1.html)