1. 程式人生 > >為什麼我覺得electron是個尷尬的存在

為什麼我覺得electron是個尷尬的存在

引子

提高工作效率的兩種辦法:

  • 使用指令碼
  • 使用工具

使用指令碼是個不錯的辦法,但是指令碼有侷限性,就是不靈活。比如我要給資料庫新增一條資料,首先你得開啟一個terminal,然後敲幾個字元把指令碼執行起來,然後小心翼翼地傳幾個值,之所以要小心翼翼地是因為值的順序是有講究的,然後回車執行指令碼。 每個值的含義只有寫指令碼的人知道,其它使用者比如測試人員必須花時間學習後才能知道。使用的時候還得注意許可權問題,寫指令碼的時候還得為不同的平臺專門寫一個。

指令碼只適合做固定的事,比如釋出程式等等。開發起來還比較麻煩,所以使用工具是個非常好的辦法,動動手指頭就行了,而且有介面,所有的操作一目瞭然。

問題是沒有現成工具怎麼辦?要麼維持現狀,要麼自己造一個。

自己造一個,這恐怕不簡單,如果要跨平臺就更不容易了。如果非要自己造一個,那麼肯定要選開發起來最容易的,而且介面還要儘可能的好看,啟動速度儘可能的快。

web介面最好看,開發起來也最容易。那我們寫一個web程式不就好了嘛,這樣不好。因為web程式必須要用瀏覽器,用瀏覽器有2個不好的地方:

  • 工作中瀏覽器打開了太多的tab頁,tab頁一多就找不到自己的那一頁了,而且我們經常會右鍵“關閉右邊便籤”,一不小心就關了。
  • 不能用alt+tab切換應用

那好辦,用electron不就好了嘛。

正題

很明顯,electron幾乎是必然的選擇,也幾乎是唯一的選擇。終於進入正題了,我們就來談一談electron。

首先你安裝一個npm,建立一個package.json。然後就開始開發介面了,一切都是那麼的順暢,簡直如行雲流水。而且還用了最時髦的react,單頁面,渲染快,樣式好看,還不用寫html和css。electron大法好。

然後你開始準備實現功能了。比如你要寫一個cassandra的客戶端程式。最簡單的辦法就是在js裡直接傳送http請求,但是很抱歉cassandra不支援REST的方式訪問。
cassandra有Java的客戶端,那我用Java寫一個就好了嘛。

用Java寫好了程式碼,然後準備讓js來呼叫Java程式碼。哦,對了,js不能直接呼叫Java程式碼,我只能弄一個http server或者rpc,然後讓js呼叫。用spring boot吧,打包後太大了,而且太重了, 這裡只是為了能讓js成功呼叫Java程式碼。還是用Oracel JDK自帶的http server吧,幾句程式碼的事兒。 但是這就跟oracle的JDK綁定了呀,假如別人的linux上只有Open JDK怎麼辦? 算了,就讓他裝一個Oracle JDK吧,反正大家幾乎都用這個。

問題來了,既然都搞http server了為什麼還要用electron呢?直接用瀏覽器不就好了嘛。

可是用瀏覽器tab頁太多而且不能用alt+tab來回切換啊。

弄了半天,又繞回來了。但是我們弄明白了一個事實: electron其實就是一個“單標籤的瀏覽器”!

既然這樣,你還不如在系統上多裝幾個瀏覽器,開啟一個瀏覽器,只開一個標籤頁,專門用來跑你的程式。而且還能用alt+tab來回切換。

你說說用electron還有什麼意思?

弄了半天,眼看就要完成了,總不能半途而廢吧。好,繼續往前走。

問題又來了,我把這個http server部署在哪兒呢?是放在本地呢還是放在局域網裡的伺服器裡呢? 顯然是放在本地好,因為這是客戶端程式,在任何電腦上都能用。

我怎麼啟動這個http server呢?打成可執行jar,然後用指令碼啟動它。

那好吧,寫一個startup.bat和startup.sh。

問題又來了,我什麼時候呼叫這個啟動指令碼呢?electron的啟動速度已經很慢了,再加上這個豈不是更慢?雖然我的http server啟動的非常快,但是我覺得還是在electron啟動之後再啟動http server比較好。嗯,就這樣吧。

好,開始打包。呀,electron打包怎麼卡住不動了?哦,原來是因為我用了cnpm。用cnpm安裝的包所有的包都是扁平化的安裝,展開後文件太多了,所以打包的非常慢。 哎,還是刪了,重新用npm安裝吧。

問題來了,npm install 要等好長一段時間啊。 算了,眼看都要成功了,就忍忍吧。然後打包速度就非常快了。

終於打包好了,立馬啟動一下看看。 7-10秒。 重啟機器試試,不錯,大概6秒左右,估計是我的固態硬碟速度不夠快吧。
看看打包後的檔案大小, 222MB, 記憶體100MB,這些都可以接受,就是這啟動速度不大能接受。

總結

更正一個錯誤,終於知道你們攻擊的點在哪兒了。
electron是把nodejs和chromium的js上下文合併在一起了,就是不分前臺js和後臺js。

不過這不影響,我想說的是:即使這樣有些功能還是得用其他語言完成,這個其他語言通常是你最熟悉的。那麼js跟其他語言通訊就是個問題,最容易想到的就是http。當然你也可以用類似於node-java這樣的東西,不過我猜大多數人都會繼續使用http。你去谷歌搜一下,atom論壇有人問"如何呼叫java?"
有回答用http。問題就在這兒,只要你用了http,electron的意義就不大了,因為跟瀏覽器沒有區別了。

我這這篇文章的目的就是想告訴你們:你們在使用electron的時候不要還想著用spring boot之類的東西,這幾乎是錯誤的想法。因為有了http server這時候使用electron就沒意義了,直接弄成web應用,用現成的瀏覽器開啟即可,何必費那功夫再弄一個呢。

再更正一個說法:

electron是什麼?用了http,它就是一個單標籤頁的瀏覽器。不用http,它是原生的桌面應用。

最想說的說完了,後面的可以不用看了,當然也可以當笑話看看。不要再回復了。

~~
什麼情況下應該使用electron?

所有的功能都能用客戶端js實現,不需要啟動一個本地http server。這個本地http server的作用就相當於一個RPC,為了能讓客戶端js呼叫你的後端程式碼。你的後端程式碼可以是Java, Python, C++等。因為有些情況下你必須使用後端語言來實現某些功能, 不是所有的服務都提供REST api的。

你看Atom, VS Code雖然也是用electron做的,但是它的功能基本上都能用js搞定。也許你會說VS Code能編譯C++/Java程式碼,難道js能實現這個嗎?
我不知道他們是怎麼實現的。我猜測他們是用了服務端的js實現的,我們知道node.js有一個node-gyp模組可以呼叫C++程式碼。

我說的是客戶端js。就是在頁面上執行的js。客戶端js是不能直接呼叫Java程式碼的,它只能傳送http請求。electron的確有一個electron-java模組,可以用js呼叫Java程式碼,但是我試了一下沒成功。 這需要一些學習成本。

目前為止electron沒有解決前後臺通訊的問題,而是讓我們繼續使用http的方式,還用解決cors的問題,我就覺得這是在欺騙。你根本不是在開發桌面應用,是完完全全在開發web應用。只不過你不是在真正的瀏覽器上執行,而是在一個單標籤的瀏覽器上執行罷了。你單獨開一個瀏覽器開啟你的頁面,跟使用electron開啟頁面有什麼區別?這算哪門子的桌面應用?

總之一句話,只要你用了http,那麼electron就充當一個瀏覽器的作用。 你用http無非就是為了能呼叫其他語言的程式碼,用rpc也是一樣。顯然用http更方便, 只要你用了http,那麼electron就充當一個瀏覽器的作用。每個app都包含了瀏覽器。app之間不能共享瀏覽器那部分程式碼很浪費。最尷尬的是你你明明用了http,本質上就是一個web app,用瀏覽器得了,還用什麼electron啊。

最後再囉嗦一句:

我理想中的electron應該跟zserge/webview類似。這裡js就可以非常容易地直接呼叫C程式碼,我可以在C程式碼裡建立一個jvm,然後就可以用上Java了。如果你用其它語言也類似。這裡就不需要管什麼http,也沒有煩人的cors了。 雖然開發步驟多了點,不過我覺得這看起來更像桌面應用。唯一的遺憾就是使用者必須安裝一個JDK。否則打包的時候就要把JDK打包進來,打包後文件就變大了。

補充一點,非常重要的一點,忘了說了:
我的程式要能連線不同版本的資料庫。
比如一個客戶端程式,可以連任何版本的cassandra,我的想法是自定義一個parent last classloader,然後載入不同的jar包,這樣就不會有jar包衝突。實際上我前一篇部落格裡就是這樣做的。先用c程式碼啟動一個虛擬機器,然後再載入jar包。

如果不這樣子做,就算你找到了cassandra的npm包,那也只能連一個版本的cassandra,否則你得解決同一個包不同版本的衝突問題(類似於jar包衝突)

請大家看到後不要再回復了,這是部落格不是論壇。
~~