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