摘要:在菜單中,我想點擊子菜單打開一個網(wǎng)站,那么就可以用到方法,則會在默認瀏覽器中打開打包應用其實將程序打包成桌面應用才是比較麻煩的事。
前言
Electron 是一個搭建跨平臺桌面應用的框架,僅僅使用 JavaScript、HTML 以及 CSS,即可快速而容易地搭建一個原生應用。這對于想要涉及其他領域的開發(fā)者來說是一個非常大的福利。
項目介紹倉庫地址:lin-xin/calculator
我這里通過 Electron 實現(xiàn)了仿 iPhone 的計算器,通過菜單可以切換橫屏和豎屏,橫屏有更多的運算。而對于 JavaScript 進行浮點數(shù)計算來說,精度丟失是個很大問題,所以我這里使用了第三方庫 math.js 來解決這個精度的問題。
盡可能的實現(xiàn)了跟 iPhone 一樣的運算:
1 + 2 × 3 = 7
3 += 6 (再按 = 等于 9)
0.1 + 0.2 = 0.3 (浮點數(shù)精度處理)
不過我下面并不是要講計算器,而是用到的 Electron 的知識點。
生命周期在主進程中通過 app 模塊控制整個應用的生命周期。
當 Electron 完成初始化時觸發(fā) ready 事件:
app.on("ready", () => { // 創(chuàng)建窗口、加載頁面等操作 })
當所有的窗口都被關閉時會觸發(fā) window-all-closed 事件:
app.on("window-all-closed", () => { if(process.platform !== "darwin"){ app.quit(); // 退出應用 } })
在開發(fā)中發(fā)現(xiàn),沒有監(jiān)聽該事件,打包后的應用關閉后,進程還保留著,會占用系統(tǒng)的內(nèi)存。
窗口本來我們的 html 只顯示在瀏覽器中,而 electron 提供了一個 BrowserWindow 模塊用于創(chuàng)建和控制瀏覽器窗口,我們的頁面就是顯示在這樣的窗口中。
創(chuàng)建窗口通過關鍵字 new 實例化返回 win 對象,該對象有豐富的方法對窗口進行控制。
win = new BrowserWindow({ width: 390, // 窗口寬度 height: 670, // 窗口高度 fullscreen: false, // 不允許全屏 resizable: false // 不允許改變窗口size,不然布局就亂了啊 });加載頁面
窗口創(chuàng)建完是一片空白的,可以通過 win.loadURL() 來加載要顯示的頁面。
const path = require("path"); const url = require("url"); win.loadURL(url.format({ // 加載本地的文件 pathname: path.join(__dirname, "index.html"), protocol: "file", slashes: true }))
也可以直接加載遠程鏈接 win.loadURL("http://blog.gdfengshuo.com");
菜單桌面應用菜單欄是最常見的功能。Electron 提供了 Menu 模塊來創(chuàng)建原生的應用菜單和 context 菜單,
const template = [ // 創(chuàng)建菜單模板 { label: "查看", submenu: [ {label: "豎屏", type: "radio", checked: true}, // type 屬性讓菜單為 radio 可選 {label: "橫屏", type: "radio", checked: false}, {label: "重載",role:"reload"}, {label: "退出",role:"quit"}, ] } ] const menu = Menu.buildFromTemplate(template); // 通過模板返回菜單的數(shù)組 Menu.setApplicationMenu(menu); // 將該數(shù)組設置為菜單
在子菜單中,通過點擊豎屏或橫屏來進行一些操作,那就可以給 submenu 監(jiān)聽 click 事件。
const template = [ { label: "查看", submenu: [ { label: "橫屏" click: () => { // 監(jiān)聽橫屏的點擊事件 win.setSize(670,460); // 設置窗口的寬高 } } ] } ]主進程和渲染進程通信
雖然點擊橫屏的時候,可以設置窗口的寬高,但是要如何去觸發(fā)頁面里的方法,這里就需要主進程跟渲染進程之間進行通信。
主進程,可以理解為 main.js 用來寫 electron api 的就是主進程,渲染進程就是渲染出來的頁面。
ipcMain在主進程中可以使用 ipcMain 模塊,它控制著由渲染進程(web page)發(fā)送過來的異步或同步消息。
const {ipcMain} = require("electron") ipcMain.on("send-message", (event, arg) => { event.sender.send("reply-message", "hello world") })
ipcMain 監(jiān)聽 send-message 事件,當消息到達時可以調(diào)用 event.sender.send 來回復異步消息,向渲染進程發(fā)送 reply-message 事件,也可以帶著參數(shù)發(fā)送過去。
ipcRenderer在渲染進程可以調(diào)用 ipcRenderer 模塊向主進程發(fā)送同步或異步消息,也可以收到主進程的相應。
const {ipcRenderer} = require("electron") ipcRenderer.on("reply-message", (event, arg) => { console.log(arg); // hello world }) ipcRenderer.send("anything", "hello everyone");
ipcRenderer 可以監(jiān)聽到來自主進程的 reply-message 事件并拿到參數(shù)進行操作,也可以使用 send() 方法向主進程發(fā)送消息。
webContentswebContents 是一個事件發(fā)出者,它負責渲染并控制網(wǎng)頁,也是 BrowserWindow 對象的屬性。在 ipcMain 中的 event.sender,返回發(fā)送消息的 webContents 對象,所以包含著 send() 方法用于發(fā)送消息。
const win = BrowserWindow.fromId(1); // fromId() 方法找到ID為1的窗口 win.webContents.on("todo", () => { win.webContents.send("done", "well done!") })remote
remote 模塊提供了一種在渲染進程(網(wǎng)頁)和主進程之間進行進程間通訊(IPC)的簡便途徑。在 Electron 中,有許多模塊只存在主進程中,想要調(diào)用這些模塊的方法需要通過 ipc 模塊向主進程發(fā)送消息,讓主進程調(diào)用這些方法。而使用 remote 模塊,則可以在渲染進程中調(diào)用這些只存在于主進程對象的方法了。
const {remote} = require("electron") const BrowserWindow = remote.BrowserWindow // 訪問主進程中的BrowserWindow模塊 let win = new BrowserWindow(); // 其他的跟主進程的操作都一樣
remote 模塊除了可以訪問主進程的內(nèi)置模塊,自身還有一些方法。
remote.require(module) // 返回在主進程中執(zhí)行 require(module) 所返回的對象 remote.getCurrentWindow() // 返回該網(wǎng)頁所屬的 BrowserWindow 對象 remote.getCurrentWebContents() // 返回該網(wǎng)頁的 WebContents 對象 remote.getGlobal(name) // 返回在主進程中名為 name 的全局變量(即 global[name]) remote.process // 返回主進程中的 process 對象,等同于 remote.getGlobal("process") 但是有緩存shell 模塊
使用系統(tǒng)默認應用管理文件和 URL,而且在主進程和渲染進程中都可以用到該模塊。在菜單中,我想點擊子菜單打開一個網(wǎng)站,那么就可以用到 shell.openExternal() 方法,則會在默認瀏覽器中打開 URL
const {shell} = require("electron"); shell.openExternal("https://github.com/lin-xin/calculator");打包應用
其實將程序打包成桌面應用才是比較麻煩的事。我這里嘗試了 electron-packager 和 electron-builder。
electron-packagerelectron-packager 可以將項目打包成各平臺可直接運行的程序,而不是安裝包。
先使用 npm 安裝: npm install electron-packager -S
運行打包命令:
electron-packager ./ 計算器 --platform=win32 --overwrite --icon=./icon.ico
打包會把項目文件包括 node_modules 也一起打包進去,當然可以通過 --ignore=node_modules 來忽略文件,但是如果項目中有用到第三方庫,忽略的話則找不到文件報錯了。
正確的做法就是嚴格區(qū)分 dependencies 和 devDependencies,打包的時候只會把 dependencies 的庫打包,而使用 cnpm 安裝的會有一大堆 .0.xx@xxx 的文件,也會被打包,所以最好不要用 cnpm
electron-builderelectron-builder 是基于 electron-packager 打包出來的程序再做安裝處理,將項目打包成安裝文件。
安裝:npm install electron-builder -S
打包:electron-builder --win
打包過程中,第一次下載 electron 可能會出現(xiàn)連接超時,可以使用 yarn 試試。還有 winCodeSign 和 nsis-resources 也可能會失敗,可以參考 electron-builder/issues 解決。
總結Electron 用起來還是相對容易的,可以創(chuàng)建個簡單的桌面應用,只是打包的過程比較容易遇到問題,網(wǎng)上好像也有一鍵打包的工具,沒嘗試過。以上也都是基于 windows 7 的實踐,畢竟沒有 Mac 搞不了。
更多文章:linxin/blog文章版權歸作者所有,未經(jīng)允許請勿轉載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/85222.html
摘要:進程主進程在里,運行里腳本的進程被稱為主進程。渲染進程由于使用來展示頁面,所以的多進程結構也被充分利用。當一個實例被銷毀后,相應的渲染進程也會被終止。在,我們提供用于在主進程與渲染進程之間通訊的模塊。 Github 系列文章地址筆者前兩天心血來潮做了個MACOS下可以進行OCR圖文識別的小工具,發(fā)現(xiàn)Electron 在1.x之后API發(fā)生了挺大的變化,估計也是我好久沒碰了,所以打算把這...
摘要:在考慮宇航員的生命安全時,輕微的打嗝或者服務中斷都會釀成生死事故。也許最大的挑戰(zhàn)來自谷歌主導的簡稱。在最近的開發(fā)者峰會,以及今年的會議上,谷歌都為安排了大量討論。由微軟提供,是廣受歡迎的編輯器,到月份已經(jīng)獲得了超過五百萬用戶。 譯者:安冬 (滬江Web前端開發(fā)工程師)本文原創(chuàng)翻譯,轉載請注明作者及出處。原文地址:http://developer.telerik.com/... 技術世界...
摘要:于是乎,就想著把自己寫的這個小項目打包成桌面端,方面每次打開電腦就能看。然后繼續(xù)運行,然后白屏習慣性的首次失敗。。解決方法進入文件夾下的將其中的修改為相對路徑。再次運行,成功將的項目,顯示為桌面應用。總結至此,打包桌面端就這樣完成了。 背景 showImg(https://segmentfault.com/img/bVYowg?w=1922&h=862); 最近在學習RxJS,平時邊看...
摘要:說起桌面應用,想必大家使用過的就已經(jīng)海了去了。那么現(xiàn)在我們就來生成一個程序包吧最后生成的可執(zhí)行程序出就現(xiàn)在了如下位置愉快的雙擊使用吧 說起桌面應用,想必大家使用過的就已經(jīng)海了去了。什么暴風影音、QQ、skype之類的,早已不是新鮮事!不過大家有沒有了解過如何編寫一個桌面應用?歷史上,我們都有哪些方式去編寫桌面應用呢? 實際上,桌面應用的歷史并不算久遠,不去查找各種資料,僅憑記憶,我能想...
閱讀 2565·2023-04-25 20:05
閱讀 2891·2023-04-25 17:56
閱讀 2204·2021-10-14 09:49
閱讀 2687·2019-08-29 15:10
閱讀 2926·2019-08-29 12:25
閱讀 421·2019-08-28 18:23
閱讀 762·2019-08-26 13:26
閱讀 1375·2019-08-23 18:21