Electron 入門
前陣子花了些時間用 Electron 寫了個桌面應用程式,覺得有些資訊應該記錄一下,其實我覺得 Electron 的文件弄得超爛的,非常沒有 Github 的水準,Github 當初能夠起來,我認為一個很大的原因就是文件做的很好,而且在頁面上都會提供相對應操作的說明文件,不只讓網站的易用性提昇很多,連帶的也推廣了 Git 的使用,算是相輔相成起來的,不過 Electron 剛推出的時候,我就覺得,這是有文件嗎?甚至讓我有個印像是,我們雖然推出 Electron 但是沒很想讓你們用,所以文件隨便寫寫。
為什麼這樣說,拿現在最新版 0.3.0 來說,其實這應該只是自動產生的文件,整頁的第一篇文章是 Application distribution,這真的沒有哪裡搞錯嗎?而且這份文件還很爛,有關鍵的地方沒說,之後會講。總之,要開始寫 Electron App 應該要看的是 Quick Start 才對,這份文件用了一個很簡單的範例讓你開始可以跑 Electron App,只要會寫網頁,從這邊就可以開始做 Electron App,但是一個應用程式哪有這麼單純,只靠 Web 端的技術一定是有不足的,例如我要做的程式就需要讀取 key 去登入 SSH 然後做事情,這登入 SSH 然後做事的部分用的是 node 的 code,不能跑在瀏覽器環境,在 Electron 的架構下,瀏覽器環境稱為 renderer,而另外一邊用來起始 renderer process 的則稱為 main process,要登入 SSH 的 code 就要寫在 main process 這邊,那兩邊要怎麼溝通呢?Electron 提供了 IPC 模組來用。
IPC 模組應該是稱為 Inter Process Communication 吧,我覺得這在 Electron App 開發當中應該是超重要的一部份,結果在 Quick Start 那篇文章中竟然沒有範例介紹,只有簡單的一句話說如果兩邊要溝通要用這個(或是另外一個 remote 模組),而且點過去也只有 API 文件,沒有範例,後來出的 remote 模組的文件才有範例說明,總之這樣弄來弄去還是有解決兩邊的溝通問題,所以下一個遇到的,就是我要怎麼讓使用者選檔案了。
因為 Electron 是跨平台的,我的程式設計是用 private key 去登入遠端的機器做事情,Linux 或 OSX 都可以假設 key 的位置,但是 Windows 不行,所以我就要提供可以讓使用者選檔案的功能,這部分文件也是沒有好好的連結,你看完 Quick Start,看一遍文件目錄,其實都看不出來到底要怎麼做到這件事,事實上它被稱為 dialog,這不把整份 API 文件翻完真的不知道是放在這名字下面。
然後,Electron 的 renderer process 端雖然和瀏覽器環境幾乎一樣,不過還是有些差異,一部份是 Chrome 引擎的問題,例如最近的fetch
,在 renderer process 會受到 CORS 限制,但是 XHR 不會,這是因為 fetch 還沒有檢查 Chrome 的 safety flag,所以如果要用 fetch API 接 ES6 Promise 的話,就要用 Github 的 polyfill,自己把檢查的程式碼拿掉,另外一個類似的問題是,如果要在 renderer process 中,引入第三方的 library,有兩種用法,一個是用新出現的require
來引入 npm module,或是像一般網頁一樣,直接用<script>
標籤引入 js 檔案,但是就會發生一個問題,因為 jQuery 會判斷現在的環境,然後來決定要不要 expose$
變數到 global scope 下,剛好,Electron 的環境下,雖然是要當成瀏覽器環境,但是又多了require
可以用,結果就是被誤判成在 Node 環境,想當成一般網頁環境用 jQuery 就會找不到$
,結果也是要自己去修改檢查部分的程式碼。
最後,把程式功能弄得差不多了,要打包給其他人時,發現竟然無從下手,本文開頭提到的 Application distribution 這份文件說的很簡單,就是把某個目錄換掉就好了,可是真的到了這一步才意識到,是換掉哪裡的目錄?結果只好上網找別人弄好的打包工具,這邊我用的是 electron-packager,研究一下才發現,原來是要抓 Github 上 release 那的檔案下來處理,整個過程其實還蠻不愉快的,因為根本不是難懂,而是文件作不好造成一堆時間浪費啊。