從編程模型的角度來講,使用聲明式語言聲明樣式和佈局,使用功能完備的編程語言編寫業務邏輯,算是GUI程序的一種最好的實踐了。html
最近要寫一個我的項目,因而我天然想到使用前端來寫界面。經過electron就能使用前端技術開發桌面端程序。它實際上就至關於內嵌了一個webkit瀏覽器核心,只是作了些裁剪和優化。前端
此外,前端框架使用我所熟悉的vue,不管是界面代碼仍是核心代碼都採用typescript編寫,它的靜態類型系統很強大,綜合了靜態語言和動態語言的優勢。vue
<!--more-->node
npm install --global @vue/cli # 2. 建立一個新工程,並選擇 "Manually select features (手動選擇特性)" 選項 vue create idocumentation
勾選上typescript,其它的按需勾選。python
Vue CLI v3.0.0-rc.3 ? Please pick a preset: Manually select features ? Check the features needed for your project: Babel, TS, Router, Vuex, Linter ? Use class-style component syntax? No # 是否使用class風格的組件定義 ? Use Babel alongside TypeScript for auto-detected polyfills? (Y/n)Yes ? Pick a linter / formatter config: TSLint ? Pick additional lint features: Lint on save ? Where do you prefer placing config for Babel, PostCSS, ESLint, etc.? In dedicated config files # 分離配置文件
這樣,vue腳手架就自動幫你初始化好typescript + vue項目的結構了,能夠進去看一看。linux
TSLint會對代碼的格式和規範作檢查,幫你規範格式,同時也會幫助你避免很差的習慣帶來的bug。
不過默認的配置有點嚴格,這能夠修改tslint.json
來作到,下面是個人配置:webpack
"rules": { "quotemark": [false, "single"], "indent": [true, "spaces", 2], "interface-name": false, "ordered-imports": false, "object-literal-sort-keys": false, "no-consecutive-blank-lines": false, "eofline": false, "prefer-const": false, "no-console": false, "trailing-comma": false, "max-classes-per-file": false }
若是你以爲某個檢查太嚴了,能夠關掉,具體的字段參考這裏: https://palantir.github.io/ts...git
首先安裝:github
npm install -g electron # 全局安裝方式 npm install electron # 本地安裝方式 推薦
而後編寫electron
主進程的入口代碼,這裏有個參考,將它放在項目根目錄的main.js
中:
https://github.com/electron/e...web
注意到其中有一行:
mainWindow.loadFile('index.html')
這是electron啓動時加載的前端頁面文件,固然,也可讓electron改成從url加載,就像用瀏覽器打開同樣:
mainWindow.loadURL('http://localhost:8080');
通常的工做流是,使用vue的開發服務器啓動vue的開發服務器,vue開發服務器會監聽在8080端口。
該服務器會監聽文件系統事件,當修改了項目代碼後,它會從新編譯、打包。
因此,開發時,讓electron從vue的開發服務器加載主頁面,則開發起來更方便。
最後在package.json
下加入:
"main": "main.js", // ... "scripts": { "electron": "node node_modules/electron/cli.js ." },
其中,main
字段指定項目的入口文件,也就是剛纔編寫的main.js
。
scripts
配置的含義是,當在終端運行 npm run electron
時,會執行:
node node_modules/electron/cli.js .
這段代碼會
首先,在終端裏執行:
npm run serve
它會啓動vue的調試服務器,通常監聽的是8080端口。不過,這個服務器比較智能,若是發現8080被佔用會主動換端口。若是和electron搭配使用時調試的時候要注意這一點。
若是這個時候在瀏覽器打開http://127.0.0.1:8080
也能正常訪問,可是最好仍是要在electron中調試。由於electron項目可能涉及到操做系統相關庫的調用如fs,使用瀏覽器是不支持的。
其次,終端再開一個tab,執行:
npm run electron
若是一切順利,electron的GUI就正常打開了!
可是,上面的配置還有一些問題。咱們來看vue項目的流程:
那麼,若是一個庫要想正常使用,須要知足:
然而,默認的vue打包配置是針對瀏覽器的,不會也沒有必要把操做系統相關的庫給打包進來,若是這時直接調用fs等庫,會出錯。
解決方案是修改webpack的配置,編輯vue.config.js
,內容爲:
module.exports = { configureWebpack: { target: "electron-renderer" } }
electron項目中引入sqlite真的是一種折磨!啊啊啊啊!配置出了問題,代碼都無法寫,寫了也無法運行。
搞了我一下午的時間,目前我尚未徹底解決這個問題,若是誰有好的方案請告訴我,謝謝!
目前引入sqlite會遇到兩個問題。
第一個問題則是sqlite因爲是C編寫的,安裝時會趕上編譯、連接的問題。
若是直接:
npm i --save sqlite
那麼你引入sqlite包時,確定會報錯。由於electron沒法調用sqlite的native二進制庫。
即便你解決的了問題一,這還沒完,還有一個更大的問題。
前面說過vue程序代碼是須要被webpack編譯、打包的,然而webpack打包並不能打包native模塊,像sqlite這種的。
這裏提到,這不是bug,這是feature:https://github.com/mapbox/nod...
是不行的!你還須要將sqlite的二進制庫文件連接到electron的二進制文件上去,對的,就像你配置C或C++程序那樣恐怖。好在有現成的工具,執行:
npm i --save-dev electron-rebuild ./node_modules/.bin/electron-rebuild
它會從新編譯連接electron。至於能不能成功,看運氣吧。
我在Windows下嘗試了下,一會說須要python環境,一會網絡連接又不行要下什麼預編譯包,總之事情不少。
後來在linux環境下嘗試了,成功了。以後在electron的主進程裏,也就是前面說的main.js入口文件中,嘗試了下發現可使用。
方案一解決了問題一。那麼還有問題二沒有解決。
咱們梳理下如今手上的問題:
那麼,一種很天然而然的想法是,讓實際的sqlite調用在主進程執行,渲染進程經過IPC方式和主進程通訊。
若是把這種過程封裝起來,即渲染進程中調用某個包裝類來調用sqlite3,而包裝類會將對應的調用信息經過IPC發送給主進程,主進程真正調用sqlite3模塊來完成操做。
這種方式封裝了就是遠程過程調用(RMI)了,若是需求不高也能夠不封裝。
方案三則是用其它的替代思路了。有一個叫作sql.js
的庫,也可以操做sqlite。
這個庫頗有意思,它純粹用js實現的。怎麼作到的?性能能好嗎?
準確的說不是js。這個庫不是手寫的代碼,它是使用Emscripten將sqlite的C語言實現編譯成asm.js。
而asm.js是一個js的嚴格子集,模型上和C更能對應上去,一旦js引擎發現運行的是asm.js,就跳過語法分析直接轉爲彙編語言。
可是它有幾個缺點:
若是在electorn中要拿它暫時用一用,則須要把數據庫徹底讀入到內存中操做。處理很差,內存會爆炸的。
好在我這裏須要用的sqlite只是存存元數據,幾十k大小,仍是能勉強用用到。先臨時用這個頂上,封裝一層,寫後續的代碼。前端和node發展很快,等之後有人弄出easy的解決方案了,再切換回sqlite模塊。
方案四則是看看能不能改下項目的技術選型,要不換個其它的嵌入式數據庫?
electron的優勢在於大大下降了開發成本,自己前端的方式開發界面就是一種良好的實踐的,而前端蓬勃發展的今天又有大量的框架和組件庫可供直接調用。
記得大學裏寫過GTK和Qt的圖形界面,對比之下,傳統的Qt寫界面很是麻煩費事,並且也遠遠沒有前端漂亮,動態性也差一大截。
不過electron的缺點在於打包後體積太大,並且運行性能不高。不過通常的場景中,這點缺點問題不大。