【Electron】酷家樂客戶端開發(fā)實踐分享 — 入坑篇

作者:鐘離窗慎,酷家樂PC客戶端負(fù)責(zé)人
原文地址:https://webfe.kujiale.com/electron-ku-jia-le-ke-hu-duan-kai-fa-shi-jian-fen-xiang-ru-keng-zhi-nan/
酷家樂客戶端:下載地址 https://www.kujiale.com/activity/136
文章背景:在酷家樂客戶端在V12改版成功后鹊碍,我們積累了許多的寶貴的經(jīng)驗和最佳實踐。前端社區(qū)里關(guān)于Electron知識相對較少步责,因此希望將這些內(nèi)容以系列文章的形式分享出來。
系列文章:

本文的初衷

Electron所使用的技術(shù)棧(JavaScript潜慎、NodeJs搀玖、HTML莉炉、CSS)和web前端工程師完美契合。于是陕悬,越來越多的前端工程師题暖,用Electron來開發(fā)桌面客戶端的開發(fā),我也是其中的一員捉超。

雖然Electron技術(shù)棧對前端工程師比較友好胧卤,但是概念較多,和web前端開發(fā)還是有很大差別的拼岳,寫個入坑指南希望能幫助讀者快速上手Electron枝誊。

了解客戶端

首先拋出一個問題,web應(yīng)用是桌面客戶端嗎惜纸?顯然不是叶撒。那么,問題來了耐版,什么樣的軟件才是桌面客戶端呢祠够?我們既然要從web前端轉(zhuǎn)到客戶端開發(fā),那么就需要了解客戶端椭更,就像我們當(dāng)初了解web應(yīng)用一樣哪审。

回到剛剛那個問題,桌面客戶端有兩個重要的特點:

  1. 獨立運行于操作系統(tǒng)上(桌面客戶端只是PC虑瀑,那么限定windows、MacOS叽奥、linux這幾個主流PC操作系統(tǒng))
  2. 有自己的GUI(用戶圖形界面 graphical user interface)

web應(yīng)用有自己的GUI朝氓,必須在瀏覽器中執(zhí)行,因此不是桌面客戶端赵哲。

瀏覽器能直接運行在操作系統(tǒng)上枫夺,而且有自己的GUI橡庞,因此瀏覽器是桌面客戶端。

Electron的能力

在剛剛接觸Electorn的時候丑勤,文檔看的我是眼花繚亂法竞。在某個加班的深夜爪喘,我不禁對天長嘆:這個東西到底能干啥?

這東西能干啥泛豪?在經(jīng)歷了Electron的反復(fù)摩擦之后诡曙,我總結(jié)了Electron的幾個關(guān)鍵能力:

  1. NodeJs全部能力,與操作系統(tǒng)交互
    • operation system 與操作系統(tǒng)相關(guān)的操作
    • HTTP(s)劝萤、HTTP2
    • process床嫌、child process 進程相關(guān)
    • file system 文件系統(tǒng)
    • ...省略
  2. Electron提供的基礎(chǔ)模塊厌处,主要與操作系統(tǒng)交互
    • app 主進程聲明周期管理阔涉,控制MacOS任務(wù)欄dock瑰排、windows任務(wù)欄taskbar
    • BrowserWindow 控制窗口,在MacOS和windows中窗口非常重要郭毕!
    • screen 操作用戶顯示器
    • globalShortcut 系統(tǒng)級別快捷鍵
    • ...省略
  3. Chromium提供的能力显押,主要提供GUI圖形界面
    • 解析HTML乘碑、CSS兽肤、JS
    • ajax請求
    • cookie资铡、localstorage
    • ...省略

能力越大笤休,責(zé)任越大

如果用戶安裝了我們的桌面客戶端店雅,那么我們的軟件在用戶電腦上運行時闹啦,就有了非常大的權(quán)利辕坝,這是把雙刃劍酱畅。

用戶選擇了我們的軟件圣贸,我們也要對用戶的電腦負(fù)責(zé)。能力越大滑负,責(zé)任也就越大:

1.注意內(nèi)存的占用矮慕,特別是chromium,簡直是內(nèi)存怪獸瘟斜÷菥洌可以通過os來獲取用戶電腦的配置蛇尚,然后根據(jù)電腦的配置和可用資源取劫,來制定合理的策略谱邪。

  1. 為軟件增加代碼簽名惦银,提升安全性
  2. 謹(jǐn)慎操作注冊表璧函、用戶敏感目錄

一旦被貼上【流氓軟件】、【不好用】的標(biāo)簽撩幽,就很難再改變用戶的印象了窜醉。

主進程、渲染進程

整體執(zhí)行流程静汤,展示了主進程和渲染進程的關(guān)系

生命周期

主進程:從整個應(yīng)用啟動到結(jié)束,該進程一直存在侠碧。主進程只有一個弄兜。

渲染進程:主進程可用創(chuàng)建/銷毀渲染進程替饿,因此渲染進程的生命周期是不固定的视卢。渲染進程可以有多個腾夯。

執(zhí)行環(huán)境

渲染進程可用模塊

主進程可用模塊

在Electron的API文檔中,會在文檔頂部標(biāo)識該模塊在哪個進程可用榨呆,例如:ipcRenderer

職責(zé)劃分

主進程 渲染進程
控制app的生命周期,為app注冊關(guān)鍵事件 解析HTML庸队,渲染窗口內(nèi)容
阻止一些默認(rèn)行為积蜻,例如webContents的跳轉(zhuǎn)、download事件的默認(rèn)行為等等(在渲染進程無法做到) 處理窗口的交互邏輯
創(chuàng)建BrowserWindow彻消,也就是渲染進程竿拆。合理設(shè)置窗口的參數(shù),控制窗口的生命周期(例如何時銷毀窗口)宾尚,決定BrowserWindow加載何處的HTML 與主進程通信丙笋,實現(xiàn)高級交互

窗口、前端資源

我們回顧一下剛剛講到的執(zhí)行流程煌贴,其中有一個有趣的點御板,就是Electron的窗口會加載一個HTML來渲染窗口的內(nèi)容。

HTML牛郑,以及HTML加載的css钉答、js文件砌创,統(tǒng)稱為前端資源

如果不加載HTML的,客戶端還能用嗎颂翼?不妨來試試

    // main process
    const win1 = new BrowserWindow();
    const win2 = new BrowserWindow();

上述代碼在主進程中執(zhí)行呻疹,創(chuàng)建了兩個窗口,窗口并沒加載HTML文件。但是窗口卻是真實存在的,帶有系統(tǒng)標(biāo)準(zhǔn)的控制欄占贫,可拖動厢汹,是貨真價實的系統(tǒng)窗口!

兩個空白窗口

我們可以發(fā)現(xiàn)条获,前端資源和窗口是分離的。由主進程創(chuàng)建的的窗口(BrowserWindow)称诗,既是一個系統(tǒng)原生窗口袜香,同時也是一個加載&渲染前端資源的容器

窗口通常會通過file協(xié)議和http(s)協(xié)議來加載前端資源欢策,接下來我們看看這兩種方式的區(qū)別辣卒。

通過file協(xié)議加載HTML

在Electron的官方入門例子中啡莉,就是通過file協(xié)議來加載HTML的

通過file協(xié)議加載HTML疗杉,無論有沒有網(wǎng)絡(luò),都可以加載到HTML文件,這是file協(xié)議核心優(yōu)勢言蛇。缺點也比較明顯:

  1. 如果頁面資源要更新,那么只能通過發(fā)版來解決(如果你用webview婿斥,那么webview的內(nèi)容就可以自動更新,不過webview也需要有網(wǎng)絡(luò)才能加載)
  2. 在file協(xié)議下,無法通過ajax來請求數(shù)據(jù)(協(xié)議不同)勘高,只能通過NodeJs的http(s)模塊來發(fā)起網(wǎng)絡(luò)請求

通過http協(xié)議加載HTML

通過http協(xié)議加載HTML宾抓,優(yōu)點是可以隨時通過web頁面的部署孵班,更新渲染進程的資源折柠,并且在https協(xié)議下,你可以在頁面中使用前端熟悉的ajax請求來獲取數(shù)據(jù)扇售。

當(dāng)然前塔,缺點也比較明顯:

  1. 沒有網(wǎng)絡(luò),并且在你沒有做HTML的緩存時承冰,你的窗口內(nèi)容無法加載
  2. 必須通過https來加載华弓,保證頁面內(nèi)容的安全性

代碼示例

方便讀者更好理解上文的內(nèi)容,寫了一個小demo困乒,源代碼地址 https://github.com/littlecold233/electron-demo寂屏,例子有以下特點:

  • 創(chuàng)建主窗口,阻止關(guān)閉主窗口關(guān)閉的默認(rèn)事件,不銷毀窗口迁霎。(大部分客戶端的主窗口吱抚,關(guān)閉主窗口的時候,實際上是隱藏了該窗口考廉,例如QQ秘豹、微信)

  • 應(yīng)用退出時,會嘗試關(guān)閉所有窗口昌粤,再退出應(yīng)用既绕。如果主窗口的關(guān)閉行為默認(rèn)事件被阻止,那么會導(dǎo)致主窗口無法關(guān)閉涮坐,整個應(yīng)用無法退出凄贩。因此使用forceQuit這個變量來控制。

  • 使用http或者file協(xié)議加載窗口前端資源(例子中袱讹,默認(rèn)加載的是微信)


const { app, BrowserWindow } = require('electron')

async function main () {
  await app.whenReady();

  let forceQuit = false;

  const majorWindow = new BrowserWindow({
    title: '主窗口',
    width: 1000,
    height: 750,
    minWidth: 1000,
    minHeight: 750,
    backgroundColor: '#f2f2f2',
  }); // 主窗口

  // 阻止標(biāo)題更新
  majorWindow.on('page-title-updated', (e) => {
    e.preventDefault();
  });

  majorWindow.on('close', (e) => {
      // 用戶希望退出的時候疲扎,不作處理,默認(rèn)會銷毀這個窗口
      if (forceQuit) return;
      e.preventDefault();

      // macOS全屏的處理
      if (majorWindow.isFullScreen()) {
        majorWindow.once('leave-full-screen', () => {
          majorWindow.hide();
        });
        majorWindow.setFullScreen(false);
      } else {
        majorWindow.hide();  // 隱藏窗口
      }
  });

  // 點擊dock打開主窗口
  app.on('activate', () => {
    majorWindow.show();
  });

  // 用戶使用cmd + Q廓译、代碼中調(diào)用app.quit等情況
  // 此時用戶希望能夠退出應(yīng)用评肆,因此將forceQuit改為true
  app.on('before-quit', () => {
    forceQuit = true;
  });
  
  app.dock.setIcon('./img/icon.png'); // 在app打包后,這一句代碼其實是不需要的

  majorWindow.loadURL('https://wx.qq.com'); // http協(xié)議加載前端資源非区,隨便加載一個微信試試
  // majorWindow.loadURL('file://index.html'); // file協(xié)議加載前端資源

}

main();

在本地跑一下這個例子
微信測試

最后

歡迎大家在評論區(qū)討論瓜挽,技術(shù)交流 & 內(nèi)推 -> zhongli@qunhemail.com

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市征绸,隨后出現(xiàn)的幾起案子久橙,更是在濱河造成了極大的恐慌,老刑警劉巖管怠,帶你破解...
    沈念sama閱讀 222,590評論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件淆衷,死亡現(xiàn)場離奇詭異,居然都是意外死亡渤弛,警方通過查閱死者的電腦和手機祝拯,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,157評論 3 399
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來她肯,“玉大人佳头,你說我怎么就攤上這事∏绨保” “怎么了康嘉?”我有些...
    開封第一講書人閱讀 169,301評論 0 362
  • 文/不壞的土叔 我叫張陵,是天一觀的道長籽前。 經(jīng)常有香客問我亭珍,道長敷钾,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 60,078評論 1 300
  • 正文 為了忘掉前任肄梨,我火速辦了婚禮阻荒,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘峭范。我一直安慰自己财松,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 69,082評論 6 398
  • 文/花漫 我一把揭開白布纱控。 她就那樣靜靜地躺著,像睡著了一般菜秦。 火紅的嫁衣襯著肌膚如雪甜害。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,682評論 1 312
  • 那天球昨,我揣著相機與錄音尔店,去河邊找鬼。 笑死主慰,一個胖子當(dāng)著我的面吹牛嚣州,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播共螺,決...
    沈念sama閱讀 41,155評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼该肴,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了藐不?” 一聲冷哼從身側(cè)響起匀哄,我...
    開封第一講書人閱讀 40,098評論 0 277
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎雏蛮,沒想到半個月后涎嚼,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,638評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡挑秉,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,701評論 3 342
  • 正文 我和宋清朗相戀三年法梯,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片犀概。...
    茶點故事閱讀 40,852評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡立哑,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出阱冶,到底是詐尸還是另有隱情刁憋,我是刑警寧澤,帶...
    沈念sama閱讀 36,520評論 5 351
  • 正文 年R本政府宣布木蹬,位于F島的核電站至耻,受9級特大地震影響若皱,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜尘颓,卻給世界環(huán)境...
    茶點故事閱讀 42,181評論 3 335
  • 文/蒙蒙 一走触、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧疤苹,春花似錦互广、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,674評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至尤莺,卻和暖如春旅敷,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背颤霎。 一陣腳步聲響...
    開封第一講書人閱讀 33,788評論 1 274
  • 我被黑心中介騙來泰國打工媳谁, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人友酱。 一個月前我還...
    沈念sama閱讀 49,279評論 3 379
  • 正文 我出身青樓晴音,卻偏偏與公主長得像,于是被迫代替她去往敵國和親缔杉。 傳聞我的和親對象是個殘疾皇子锤躁,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,851評論 2 361

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