使用 Electron 定制化開發(fā)個(gè)人筆記客戶端軟件

Electron 介紹

作為一名熱衷于新技術(shù)的前端開發(fā)工程師胚委,如果你一直期望著打造一款桌面應(yīng)用,又不希望付出太多的精力花費(fèi)在 C++叉信、.NET 等技術(shù)上亩冬,那么使用 Electron 這種低成本的技術(shù)來開發(fā)跨平臺(tái)的桌面應(yīng)用對(duì)我們來說性價(jià)比是非常高的,從而快速地點(diǎn)亮桌面應(yīng)用開發(fā)的技能點(diǎn)硼身。

Electron 是一個(gè)基于 V8 引擎和 Node.js 的開發(fā)框架硅急,允許用 JavaScript 開發(fā)跨平臺(tái)(Windows、Mac OS X 和 Linux)桌面應(yīng)用佳遂。用 Electron 開發(fā)的應(yīng)用有很多营袜,如 Visual Studio Code、Atom丑罪、支付寶小程序 IDE(螞蟻開發(fā)者工具)等荚板。

整體架構(gòu)概覽

在這里插入圖片描述

Electron 主要包含兩類進(jìn)程,主進(jìn)程(Main Process)和渲染進(jìn)程(Renderer Process)吩屹。當(dāng)我們在啟動(dòng)一個(gè) App 時(shí)跪另,那么會(huì)先啟動(dòng)主進(jìn)程,主進(jìn)程會(huì)啟動(dòng)應(yīng)用并創(chuàng)建 native UI煤搜,隨后會(huì)在 native UI 上啟動(dòng)一個(gè)或多個(gè)的 browser window 即 web pages免绿,每一個(gè) BrowserWindow 都是一個(gè)渲染進(jìn)程 身害。在 native UI 上的不同的 browser windows 它們是獨(dú)立的沙箱環(huán)境橘茉,不同的進(jìn)程之間是互相隔離的,Electron 提供了幾種進(jìn)程之間通信的方式相恃,比如 IPC(inter-process communication)和 RPC(remote-process communication)厌衙。

主進(jìn)程(Main Process)和渲染進(jìn)程(Renderer Process)

Main Process

Electron 運(yùn)行 package.json 的 main 腳本(程序的入口)的進(jìn)程被稱為主進(jìn)程距淫,一個(gè)應(yīng)用只有一個(gè)主進(jìn)程绞绒,主進(jìn)程可以:

  • 主進(jìn)程包含了 Chromium 和 Node 的運(yùn)行時(shí)環(huán)境婶希;
  • 主進(jìn)程可以通過實(shí)例化 BrowserWindow 展示 Web 頁面,每一個(gè) Web 頁面都會(huì)運(yùn)行在它自己的 渲染進(jìn)程 中蓬衡;
  • 主進(jìn)程可以訪問原生的 API(注冊快捷鍵喻杈、創(chuàng)建菜單欄等)彤枢,如果渲染進(jìn)程需要訪問原生 API,那么需要和主進(jìn)程進(jìn)行通信筒饰,請求主進(jìn)程來進(jìn)行相關(guān)的調(diào)用缴啡,再返回給渲染進(jìn)程;
  • 主進(jìn)程可以管理所有的 Web 頁面和其對(duì)應(yīng)的渲染進(jìn)程瓷们。

Renderer Process

渲染進(jìn)程主要是用來渲染 Web 頁面业栅,并且兼容傳統(tǒng)的 Web 頁面,支持所有的 DOM API谬晕、Node API碘裕。除此之外,渲染進(jìn)程還可以通過和主進(jìn)程通信來訪問原生的 API攒钳。

在這里插入圖片描述

常用模塊的介紹

Electron 提供的模塊也是按照主進(jìn)程和渲染進(jìn)程來進(jìn)行劃分帮孔,不能的模塊只能在其對(duì)應(yīng)的進(jìn)程使用,下面介紹幾種常用到的模塊不撑。

app 模塊

app 模塊在主進(jìn)程中使用文兢。用來控制整個(gè)應(yīng)用程序的事件生命周期,常見的幾種監(jiān)聽事件有 ready焕檬、before-quit姆坚、will-quit。

const {app} = require('electron')

app.on('ready', ()=>{
  console.log('當(dāng) Electron 完成初始化時(shí)被觸發(fā)')
})

app.on('before-quit', (e)=>{
  // 可以調(diào)用 e.preventDefault() 來阻止默認(rèn)的行為(即關(guān)閉應(yīng)用程序)
  console.log('在應(yīng)用程序開始關(guān)閉窗口之前觸發(fā)')
})

app.on('will-quit', (e)=>{
  // 可以調(diào)用 e.preventDefault() 來阻止默認(rèn)的行為(即關(guān)閉應(yīng)用程序)
  console.log('在所有的 Web 窗口關(guān)閉实愚,應(yīng)用程序即將退出時(shí)觸發(fā)')
})

BrowserWindow 模塊

BrowserWindow 模塊在主進(jìn)程中使用旷偿。用來創(chuàng)建管理瀏覽器窗口,并且可以控制窗口的大小爆侣、邊框萍程、標(biāo)題欄樣式等。

const {app} = require('electron')
const isDev = require('electron-is-dev')
const path = require('path')
let  win 
const createWindow = () => {
  win = new BrowserWindow({
    show: false, // 先不顯示 Web 頁面兔仰,等加載后在顯示
    webPreferences: {
      nodeIntegration: true // Web 集成 node 環(huán)境
    },
    titleBarStyle: 'hiddenInset' //設(shè)置標(biāo)題欄樣式茫负,隱藏標(biāo)題欄, 顯示小的控制按鈕在窗口邊緣
  })
  win.maximize() //打開后自動(dòng)最大化窗口

  win.loadURL(isDev
    ? 'http://localhost:3000/'
    : `file://${path.join(__dirname, './index.html')}`)
  if (isDev) {
    win.webContents.openDevTools();
  }
  win.once('ready-to-show', () => {
    win.show()
  })
}
app.on('ready', createWindow) // 監(jiān)聽 app 啟動(dòng)后,創(chuàng)建 BrowserWindow 打開 Web 頁面

關(guān)于 BrowserWindow 的更多配置項(xiàng)參考:

https://www.electronjs.org/docs/api/browser-window#new-browserwindowoptions

ipcMain乎赴、webContents 模塊

ipcMain 模塊在主進(jìn)程中使用忍法。用來處理從渲染進(jìn)程(Web 頁面)發(fā)送出來的異步和同步信息,處理完后榕吼,也可以同步或異步將數(shù)據(jù)返回給渲染進(jìn)程饿序。

const {ipcMain} = require('electron')
// 監(jiān)聽由渲染進(jìn)程發(fā)送過來的事件,事件名稱是'renderer-process-message-listener'羹蚣,發(fā)送的數(shù)據(jù)是 data
ipcMain.on('renderer-process-message-listener', (event, data) => { 
  const backData = 'data'
  event.returnValue = backData // 回復(fù)同步信息給渲染進(jìn)程
  event.reply(backData) // 回復(fù)異步信息返回給發(fā)送過來的這個(gè)渲染進(jìn)程
  event.sender.send(backData) // 回復(fù)異步信息給主窗口這個(gè)渲染進(jìn)程
})

webContents 模塊也是用于主進(jìn)程中原探。ipcMain 主要是用來處理由渲染進(jìn)程發(fā)送過來的事件,而 webContents 則是用來由主進(jìn)程主動(dòng)往渲染進(jìn)程中發(fā)送事件:

win = new BrowserWindow()
win.webContents.send('event-name', {data:'data'}) // 在主進(jìn)程中使用,調(diào)用 browserWindow 的 send 方法進(jìn)行發(fā)送事件

ipcRenderer 模塊

在渲染進(jìn)程中咽弦,主要用到的就是 ipcRenderer 模塊徒蟆,用于在渲染進(jìn)程(Web 頁面)中發(fā)送同步或異步消息到主線程,也可以接收由主進(jìn)程回復(fù)的消息:

const { ipcRenderer } = require('electron')
// 在渲染進(jìn)程中主動(dòng)往主進(jìn)程中發(fā)送消息  ipcRenderer.sendSync 同步發(fā)送型型,ipcRenderer.send 異步發(fā)送
const backData = ipcRenderer.sendSync('synchronous-msg', {data:'data'}) 
ipcRenderer.send('asynchronous-msg', {data:'data'})

ipcRenderer.on('main-process-msg-listener', (event, data) => {

})

腳手架的搭建

下載腳手架

1. 下載:

git clone https://github.com/Aceysx/electron-startup.git

2. 安裝項(xiàng)目依賴:(在項(xiàng)目根目錄下)

npm install

3. 啟動(dòng):(在項(xiàng)目根目錄下)

 electron app/main  //啟動(dòng) app
 npm start // 啟動(dòng) web

Web 頁面啟動(dòng)成功后段审,刷新 App 窗口(Ctrl/cmd+r)加載 Web 頁面,即可以看到下面的頁面:

在這里插入圖片描述

腳手架的介紹

本 Chat 主要是為了介紹 Electron闹蒜,所以為了更加方便輕松地創(chuàng)建用戶交互界面寺枉、設(shè)計(jì)簡潔的數(shù)據(jù)狀態(tài),腳手架集成了 React绷落、Redux 和 Ant Design UI 幫助快速開發(fā)型凳。

如果讀者對(duì) React 不熟悉,也可以使用相應(yīng)的庫替換嘱函,或者直接使用 HTML/CSS/JavaScript甘畅。后續(xù)講解中涉及的 React、Redux 的相關(guān)內(nèi)容時(shí)也會(huì)做相應(yīng)的的說明往弓。

啟動(dòng)疏唾、調(diào)試

在啟動(dòng)成功后,可以看到帶有調(diào)試控制臺(tái)的 App 頁面函似,是不是很熟悉槐脏,和我們平時(shí)開發(fā)調(diào)試 Web 頁面一樣:

在這里插入圖片描述

來看看腳手架都做了什么。

目錄結(jié)構(gòu)

electron-startup
-- app
---- main.js  
-- public
---- index.html
-- src
---- ui
---- index.js
-- package.json

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
支付 ¥7.99 繼續(xù)閱讀
  • 序言:七十年代末撇寞,一起剝皮案震驚了整個(gè)濱河市顿天,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌蔑担,老刑警劉巖牌废,帶你破解...
    沈念sama閱讀 222,378評(píng)論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異啤握,居然都是意外死亡鸟缕,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,970評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門排抬,熙熙樓的掌柜王于貴愁眉苦臉地迎上來懂从,“玉大人,你說我怎么就攤上這事蹲蒲》Γ” “怎么了?”我有些...
    開封第一講書人閱讀 168,983評(píng)論 0 362
  • 文/不壞的土叔 我叫張陵届搁,是天一觀的道長缘薛。 經(jīng)常有香客問我窍育,道長,這世上最難降的妖魔是什么掩宜? 我笑而不...
    開封第一講書人閱讀 59,938評(píng)論 1 299
  • 正文 為了忘掉前任,我火速辦了婚禮么翰,結(jié)果婚禮上牺汤,老公的妹妹穿的比我還像新娘。我一直安慰自己浩嫌,他們只是感情好檐迟,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,955評(píng)論 6 398
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著码耐,像睡著了一般追迟。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上骚腥,一...
    開封第一講書人閱讀 52,549評(píng)論 1 312
  • 那天敦间,我揣著相機(jī)與錄音,去河邊找鬼束铭。 笑死廓块,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的契沫。 我是一名探鬼主播带猴,決...
    沈念sama閱讀 41,063評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼懈万!你這毒婦竟也來了拴清?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,991評(píng)論 0 277
  • 序言:老撾萬榮一對(duì)情侶失蹤会通,失蹤者是張志新(化名)和其女友劉穎口予,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體涕侈,經(jīng)...
    沈念sama閱讀 46,522評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡苹威,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,604評(píng)論 3 342
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了驾凶。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片牙甫。...
    茶點(diǎn)故事閱讀 40,742評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖调违,靈堂內(nèi)的尸體忽然破棺而出窟哺,到底是詐尸還是另有隱情,我是刑警寧澤技肩,帶...
    沈念sama閱讀 36,413評(píng)論 5 351
  • 正文 年R本政府宣布且轨,位于F島的核電站浮声,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏旋奢。R本人自食惡果不足惜泳挥,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,094評(píng)論 3 335
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望至朗。 院中可真熱鬧屉符,春花似錦、人聲如沸锹引。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,572評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽嫌变。三九已至吨艇,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間腾啥,已是汗流浹背东涡。 一陣腳步聲響...
    開封第一講書人閱讀 33,671評(píng)論 1 274
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留倘待,地道東北人软啼。 一個(gè)月前我還...
    沈念sama閱讀 49,159評(píng)論 3 378
  • 正文 我出身青樓,卻偏偏與公主長得像延柠,于是被迫代替她去往敵國和親祸挪。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,747評(píng)論 2 361

推薦閱讀更多精彩內(nèi)容