1. 程式人生 > >使用electron構建跨平臺Node.js桌面應用經驗分享

使用electron構建跨平臺Node.js桌面應用經驗分享

這樣的 目標 技術分享 兼容 targe 文檔 doc 控件 開發

最近,把團隊內經常使用的一個基於Node.js制作的小工具給做成了可視化操作的桌面軟件,使用的是electron,這裏簡單分享一下使用electron的一些經驗和心得。

一、如何使用electron把基本的開發環境給跑起來?

我是這麽處理的,electron官方提供了一個名為“electron-quick-start”的示例項目,地址為:https://github.com/electron/electron-quick-start

然後把相關資源給弄下來,如果你是下載Zip包解壓的,則資源默認都會放在一個名為“electron-quick-start-master”的文件夾中,把“electron-quick-start-master”改成你項目的名字,當然你不改也沒關系,就怕過段時間忘記,然後小手一抖,當做普通資源給刪掉了,到時候就男默女淚了。

然後安裝:

npm install

由於安裝包比較大,所以-\/要轉好幾分鐘才能裝好。如果安裝不順利,試試換成使用淘寶NPM鏡像:

npm install -g cnpm --registry=https://registry.npm.taobao.org

然後再這麽安裝:

cnpm install

技術分享

然後啟動:

npm start

然後就會出現這樣的框框:
技術分享

環境就這麽跑起來了。

Ctrl + R就可以刷新。

二、electron開發該怎麽入手?

一旦環境跑起來,接下來的工作就跟做一個網頁幾乎就沒什麽區別,加載點CSS,圖片啊,JS什麽的,就可以了。因為本質上,electron就是給你搞了一個Chrome瀏覽器的殼子,只是比傳統網頁多了一個訪問桌面文件的功能。

當然,具體操作並不可能像嘴皮子動的那麽簡單,前期還是需要了解一些基礎知識。

我們可以重點關註一下上一節安裝好的開發環境的一些資源文件,主要是index.html, main.jsrenderer.js,如下圖:
技術分享

在我看來,如果我們要開發的桌面應用只要不像QQ軟件那樣復雜,其實可以完全不用管main.js,main.js的作用就是用來顯示npm start

後出現的那個窗口的,而我們的工作只是窗口裏面內容,因此,main.js無需關心。

index.html是打開的窗口加載的頁面,可以看成是入口頁面,就是一個普通的靜態頁面啊,沒什麽特殊的。

renderer.js默認裏面就一堆註釋,用來放業務相關JS的,和網頁JS的區別在於,這裏的JS不僅可以訪問DOM,還能使用Node.js所有的API。能前能後,想怎麽玩都行。

所以,我們的工作思路就很清晰了:

  1. 先把我們桌面應用的可視窗口界面給弄出來,這個就需要使用CSS和HTML代碼了。相比網頁開發而言,開發桌面應用要更輕松,因為根本不要考慮兼容性的問題,而且很多最新的chrome特性,都可以也很愉快的玩起來。我們的CSS代碼可以外鏈線上的資源,也可以放到本地,也可以直接內聯在頁面中,非常自由,非常隨意啊,都可以。我個人建議是放在本地的,因為就算斷網了我們的桌面應用也能正常使用。

    假設一番折騰,我們的界面弄好了,類似這樣:
    技術分享

    接下來就是折騰交互了。

  2. 交互效果開發和傳統web網站一樣,很自由,你喜歡jQuery,就用jQuery,你喜歡Vue,也可以使用Vue等等,沒有什麽顧慮,就是幹!

    例如我給團隊做的這個桌面應用就是用的jQuery,最後應用跑得很暢快。

  3. 借助Node.js API或者其他第三方的npm工具或者electron API開發我們的應用。

    例如,引入Node.js API:

    const fs = require(‘fs‘);
    stat = fs.stat;
    
    const path = require(‘path‘);
    const url = require(‘url‘);

    引入第三方庫:

    const minify = require(‘html-minifier‘).minify;

    等等。

    例如我做這個桌面應用有需要選擇本地文件夾的功能,這個時候就需要借助electron API,由於我們的業務JS都是寫在renderer.js中的,並非主線程,因此,調用的使用要使用remote,例如:

    const electron = require(‘electron‘);
    
    const dialog = electron.remote.dialog;

    此時,我們想要點擊按鈕打開系統的選擇文件夾彈框就可以這麽處理:

    dialog.showOpenDialog({
        properties: [‘openDirectory‘, ‘createDirectory‘]
    }, callback);

    具體可參考electron API文檔,有中文版。

於是,簡簡單單的三步曲,我們的桌面應用功能就開發好了,邏輯還是以前Node.js工具的邏輯,多的僅僅是可視化的界面,以及參數是從輸入框等表單控件獲取。

開發的過程要比之前預估的要輕松得多,那種隨便怎麽玩都支持的感覺真的很美妙。

技術分享

三、electron開發好的應用該如何發布?

electron桌面在自己的開發環境下跑起來了,跑通了,如讓其他小夥伴也能方便快捷地使用呢?我們的目標是windows系統下直接點擊個.exe文件,Mac OS X直接點擊.app文件就可以跑起來,我們的小夥伴無需再麻煩安裝一堆node modules。

我們需要使用專門的打包工具,我是使用的electron-packager,首先全局安裝一下:

npm install electron-packager -g

然後就可以執行打包了,例如:

electron-packager . bobo --out ../electron

這段語句表示的意思是把當前文件目錄下的資源(.)命名為bobo打包到父級的electron文件夾。

此時electron-packager就會自動判別當前的操作系統打包對應的文件,例如windows系統下就會打包成.exe格式。

如果你想一次性把所有的操作系統都打包一遍,可以在上面打包語句後面加上-all

由於打包的時候會把瀏覽器內核完整打包進去,所以就算你的項目開發就幾百k的資源,但最終的打包文件估計有40到50M。

然後有一點需要特別註意一下,如果你開發的桌面要有第三方的npm模塊依賴,則你打包好的運行文件無論是跑不起來的,有打包的時候並不會把第三方的npm模塊依賴也打不進去,需要自己手動復制進去。我的做法是把第三方依賴的npm模塊打包成一個名為require-node_modules.zip文件夾,此時這個文件會一起被打包帶走,一同被放在app文件夾下,具體路徑為:

windows:\resources\app
OS X:顯示包內容 → \Contents\Resources\app

此時,只要直接解壓就可以使用了。

補充於翌日
感謝@小小瘦杜的糾正,實際上,是可以直接打包第三方的npm模塊的,就是安裝依賴的時候不要--save-dev

四、electron發布好的桌面應用如何有效升級?

我們平常的桌面軟件要升級的話,一般都需要下載完整的安裝包。electron作為桌面應用,似乎也逃脫不了這種宿命,但實際上,在絕大部分場景下,我們根本就無需要下載完整的安裝包,因為electron-packager打包的其實是瀏覽器內核和主線程控制腳本,具體的業務代碼全部都是獨立在app文件夾下的,也就是說,只要我們的桌面應用主線程邏輯不變,什麽UI樣式調整,什麽交互效果改變,什麽業務邏輯變更,我們都只要更新app文件夾下的這資源就可以了:

windows:\resources\app
OS X:顯示包內容 → \Contents\Resources\app

例如,我們的renderer.js做了一些升級改動,此時我們的小夥伴想要更新怎麽辦,無需再重新發布一個安裝包,直接把app文件夾下renderer.js切換一下就好了,非常簡單和快捷。

甚至如果有精力的話,我們桌面應用可以做成自動檢測是否有版本更新以及在線升級,升級的內容就是CSS,HTML,image或者JS這些靜態資源。

更新於2017-06-27
實際上,上面的更新升級還是很麻煩,經過我的實踐和數周的體驗,是可以實現穩定的熱更新功能的,具體看參見這篇文章:“我是如何實現electron的熱更新功能的?”。

五、結束語

有了electron,理論上所有基於的Node.js的工具都可以桌面化,例如,小圖標合並啊,圖片壓縮呀等等。

而且從本文的描述來看,基本上沒什麽難度,其實大家都可以搞一搞,因為對於設計師和小白開發人員而言,他們還是更喜歡使用可視化的東西,這其實對於提高團隊效率還是很有幫助的,比如那個設計師做了一個圖片壓縮或者合成的可視化工具,人家自然是很是歡喜的。

好了,就這些,以後再想到什麽遺漏的再補充上去。

技術分享

使用electron構建跨平臺Node.js桌面應用經驗分享