Electron从入门到精通
一,Electron 快速入門
1、簡介
? ? ? ? Electron是利用web前端技術進行桌面應用開發的一套框架,它是由Github開發的,利用HTML、CSS、JavaScript來構建跨平臺桌面應用程序的一個開源庫。Electron通過將Chromium和Node.js合并到同一個運行時環境中,并將其打包成Mac、Windowns、Linux系統下的應用來實現這一目的。
????????若想開發一個兼容多平臺的桌面應用,以往常用的技術框架有GTK、QT等,這些框架受語言限制,且學習成本較高,效率有限。目前一些基于前端技術的hybrid框架很流行,且已經在多個領域得到了廣泛的應用和驗證,比如利用前端技術+相應的打包工具可開發適配多平臺的應用(PC、微信公眾號、小程序、Android、IOS等)。Electron就是這樣一款框架,為前端技術人員利用web前端技術開發桌面應用帶來了可能,開發人員可利用已經掌握的前端技術如Html、CSS、JavaScript,以及結合一些前端技術框架:Vue、Angular、React、webpack,加之瀏覽器渲染引擎、Electron封裝的系統API快速實現一款桌面應用的開發,Electron做了大部分復雜的工作,開發人員只需要專注在核心業務和前端技術本身。同時,通過一定的優化,Electron可以做到很好的體驗。
????????目前有不少知名桌面應用采用Electron開發,如:開發人員熟知的Visual Studio Code、MongoDB桌面版管理工具、Skype桌面版、WhatsApp桌面版、HTTP網絡測試工具Postman等。
2、組成
Chromium
? ? ? ? Chromium為Electron提供了強大的UI能力,可以不考慮兼容性的情況下,利用強大的Web生態來開發界面。本質上就是chromium(chrome開源版本)瀏覽器,有最新的東西都會在chromium測試,所以electron可以體驗最新的api,這也是好處之一。其多進程架構圖如下:
簡單描述其原理:
????????主進程中的RenderProcessHost和 render 進程中的RenderProcess是用來處理進程間通信的(IPC(Inter-Process Communication,進程間通信)。
????????Render 進程中的 RenderView 內容基于 WebKit(瀏覽器引擎) 排版展示出來的
????????Render 進程中的ResourceDispatcher是用來處理資源請求的。Render 進程中如果有請求則創建一個請 求 ID,轉發到 IPC,由 Browser 進程中處理后返回。
????????Chromium 是多進程架構,包括一個主進程,多個渲染進程。
Node.js
? ? ? ? Node.js是讓Electron有了底層的操作能力,比如文件的讀寫,甚至是集成C++等等操作,并可以使用大量開源的npm包來完成開發需求
Native API
????????Native API讓Electron有了跨平臺和桌面端的原生能力,比如說它有統一的原生界面,窗口、托盤、消息通知這些。
3、涉及前端技術
????????Electron是基于Chromium和Node.js實現的,所以開發人員所需要使用到的前端技術主要包括以下方面:
????????(1)、Html、CSS、JavaScript、ES6
????????(2)、前端開發工具Vue、Angular、React等的一種
????????(3)、其他網絡、緩存、通訊等前端技術
4、架構
????????Electron 架構和 Chromium 架構類似,也是具有1個主進程和多個渲染進程。但是也有區別:
????????(1)、在各個進行中暴露了 Native API ,提供了 Native 能力
????????(2)、引入了 Node.js,所以可以使用 Node 的能力
????????(3)、但是渲染進程使用node 需要配置,下文會有所提到
????????可以簡單的理解為Electron為web項目套上了Node.js環境的殼,使得我們可以調用Node.js的豐富的API。這樣我們可以用JavaScript來寫桌面應用,拓展很多我們在web端不能做的事情。
? ? ? ? Electron的結構示意圖如下:electron核心可以分成2個部分即:主進程和渲染進程。
?主進程
????????Electron 運行 package.json 的 main 腳本的進程被稱為主進程 (只有一個)。
????????主進程特點:
????????????????主進程連接著操作系統和渲染進程,可以把她看做頁面和計算機溝通的橋梁
????????????????進程間通信、窗口管理
????????????????全局通用服務
????????????????一些只能或適合在主進程做的事情,如瀏覽器下載、全局快捷鍵處理、托盤、session
????????????????維護一些必要的全局狀態
渲染進程
????????渲染進程就是我們所熟悉前端環境了。只是載體改變了,從瀏覽器變成了window。
????????注:出于安全考慮,渲染進程是不能直接訪問本地資源的),因此都需要在主進程完成。
????????渲染進程特點:
????????????????Electron 使用了 Chromium 來展示 web 頁面,所以 Chromium 多進程架構也被使用到。
????????????????每個web頁面運行在自己的進程中。每個渲染進程是相互獨立的且只關心自己網頁。
????????????????使用BrowserWindow類開啟一個渲染進程并將這個實例運行在該進程中,當一個被銷毀后,相應的渲染進程也會被終止。
????????????????渲染進程不能調用原生資源,但同樣包含Node.js環境,所以可以引入Node.js。
主進程與渲染進程的區別
????????主進程使用 BrowserWindow 實例創建網頁。
????????每個 BrowserWindow 實例都在自己的渲染進程里運行著一個網頁。當一個 BrowserWindow 實例被銷毀后,相應的渲染進程也會被終止。
????????主進程管理所有頁面和與之對應的渲染進程。
????????由于在網頁里管理原生 GUI 資源是非常危險而且容易造成資源泄露,所以在網頁面調用 GUI 相關的 APIs 是不被允許的。如果你想在網頁里使用 GUI 操作,其對應的渲染進程必須與主進程進行通訊,請求主進程進行相關的 GUI 操作。
二,Electron 桌面環境搭建
1、安裝Node.js
(1)、默認安裝,一直next
(2)、驗證node是否安裝成功
打開cmd窗口,在命令窗口輸入命令:node -v ,如果出現版本號,即表示安裝成功
還可以查看npm的版本,在cmd命令窗口中輸入命令:npm -v
2、安裝Electron
(1)、安裝cnpm,采用淘寶鏡像安裝electron
打開cmd窗口,在命令窗口輸入命令下載安裝:
npm install cnpm -g ?--registry=https://registry.npm.taobao.org
?在cmd命令窗口中輸入命令:cnpm -v 查看版本信息
?(2)、安裝electron,全局安裝
打開cmd窗口,在命令窗口輸入命令下載安裝:cnpm install electron -g
在cmd命令窗口中輸入命令:electron -v 查看版本信息
?3、測試項目
(1)、使用WebStorm新建空項目
?(2)、在根目錄下新建一個html文件,文件名稱為helloworld.html
(3)、在根目錄下新建一個 main.js 文件,并填寫如下代碼,這個就是 Electron 的主進程文件
// 1、引入electron模塊 let electron = require('electron');// 2、創建electron引用 let app = electron.app;// 3、創建窗口引用 let BrowserWindow = electron.BrowserWindow;// 4、聲明要打開的主窗口 let mainWindow = null;app.on('ready',() => {// 設置窗口大小mainWindow = new BrowserWindow({width:300, height:200});// 加載哪個頁面mainWindow.loadFile('helloworld.html');// 監聽關閉事件,把主窗口設置為null,否則內存占用越來越多mainWindow.on('closed',() => {mainWindow = null;}) })?(4)、在終端位置直接使用命令:npm init --yes 來初始化 package.json 文件
文件生成后如下:
{"name": "electron","version": "1.0.0","description": "","main": "main.js","scripts": {"test": "echo \"Error: no test specified\" && exit 1"},"keywords": [],"author": "","license": "ISC" }(5)、運行項目,在終端位置輸入命令:electron . (注意命令最后帶 .)
三,Electron 項目實戰
1、Electron remote模塊的使用
????????Electron 的 API 方法和模塊也是分為可以在主進程和渲染進程中使用。那如果我們想在渲染進程中使用主進程中的模塊方法時,可以使用 Electro remote 來解決在渲染和主進程間的通訊。這節我們就實現一個通過Web中的按鈕打開新窗口。
(1)、在項目根目錄下,新建一個 demo1.html 文件,然后快速生成html的基本結構,編寫一個按鈕,引入渲染的js頁面。代碼如下:
<!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><title>demo1</title> </head> <body><button id="btn">打開新的窗口</button><script src="render/demo1.js"></script> </body> </html>(2)、在render文件夾下,新建一個 demo3.js 文件,然后編寫如下代碼:
// 1、獲取ID為btn的選擇器 const btn = this.document.querySelector('#btn');// 2、創建窗口引用 const BrowserWindow = require('electron').remote.BrowserWindow;// 3、打開窗口 window.onload = function (){btn.onclick = () => {newWin = new BrowserWindow({width: 300, height: 200})newWin.loadFile('test1.html')newWin.on('close', () => {newWin = null})} }(3)、在項目根目錄下創建test1頁面,然后寫入下面的代碼:
<!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>test1</title> </head> <body><h1>hello World!</h1> </body> </html>(4)、?修改 main.js ,增加全量使用node.js,內容:
// 1、引入electron模塊 let electron = require('electron');// 2、創建electron引用 let app = electron.app;// 3、創建窗口引用 let BrowserWindow = electron.BrowserWindow;// 4、聲明要打開的主窗口 let mainWindow = null;app.on('ready',() => {// 設置窗口大小mainWindow = new BrowserWindow({width:300,height:200,// 增加全量使用node.js,因為我們要使用node里的fs模塊// enableRemoteModule 設置為true,否則不允許在渲染器上使用 remotewebPreferences: { nodeIntegration: true, enableRemoteModule: true}});// 加載哪個頁面mainWindow.loadFile('demo1.html');// 監聽關閉事件,把主窗口設置為null,否則內存占用越來越多mainWindow.on('closed',() => {mainWindow = null;}) })?(5)、在終端中運行 electron . 命令,查看測試效果
2、Electron創建菜單和基本使用
(1)、在項目的根目錄下新建一個main文件夾,用于存放主進程中用到的代碼,在文件夾中新建文件menu.js,內容如下:
const { Menu, BrowserWindow } = require('electron')// 菜單模板 let template = [{label: '前端技能',submenu: [{label: 'JavaScript',// 加入click事件click: () => {win = new BrowserWindow({width: 200,height: 200,webPreferences: { nodeIntegration: true }})win.loadFile('test2.html')win.on('closed', () => {win = null})}},{ label: 'TypeScript' }]},{label: '后端技能',submenu: [{ label: 'golang' },{ label: 'Python' }]} ]// 設置菜單 let m = Menu.buildFromTemplate(template) Menu.setApplicationMenu(m)?(2)、項目根目錄新建測試文件 test2.html,內容如下:
<!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title> </head> <body> <h1>hello World!</h1> </body> </html>(3)、項目根目錄新建測試文件 demo2.html,內容如下:
<!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><title>Demo2</title> </head> <body></body> </html>?(4)、修改 main.js ,并在ready生命周期中,引入自定義菜單文件?require('./main/menu.js');
// 1、引入electron模塊 let electron = require('electron');// 2、創建electron引用 let app = electron.app;// 3、創建窗口引用 let BrowserWindow = electron.BrowserWindow;// 4、聲明要打開的主窗口 let mainWindow = null;app.on('ready',() => {// 自定義菜單require('./main/menu.js');// 設置窗口大小mainWindow = new BrowserWindow({width:300,height:200,// 增加全量使用node.js,因為我們要使用node里的fs模塊// enableRemoteModule 設置為true,否則不允許在渲染器上使用 remotewebPreferences: { nodeIntegration: true, enableRemoteModule: true}});// 加載哪個頁面mainWindow.loadFile('demo2.html');// 監聽關閉事件,把主窗口設置為null,否則內存占用越來越多mainWindow.on('closed',() => {mainWindow = null;}) })?(5)、在終端中運行 electron . 命令,查看測試效果
?3、Electron制作右鍵菜單
(1)、菜單快捷鍵綁定
????????接著上面的 demo2 ,綁定快捷鍵的屬性是?accelerator 屬性,比如我們要用快捷鍵新打開一個窗口,我們的?menu.js?代碼可以寫成這樣:accelerator:`ctrl+n`
const { Menu, BrowserWindow } = require('electron')// 菜單模板 let template = [{label: '前端技能',submenu: [{label: 'JavaScript',// 綁定快捷鍵accelerator:`ctrl+n`,// 加入click事件click: () => {win = new BrowserWindow({width: 200,height: 200,webPreferences: { nodeIntegration: true }})win.loadFile('test2.html')win.on('closed', () => {win = null})}},{ label: 'TypeScript' }]},{label: '后端技能',submenu: [{ label: 'golang' },{ label: 'Python' }]} ]// 設置菜單 let m = Menu.buildFromTemplate(template) Menu.setApplicationMenu(m)?(2)、創建右鍵菜單
????????右鍵菜單的響應事件是寫在渲染進程中的,也就是寫在根目錄下的demo2.html中的,所以要使用,就要用到remote模塊進行操作了,先來看看右鍵的相應事件,我們打開 render 文件夾,然后打開 demo2.js 文件,編寫一個右鍵菜單的監聽事件,代碼如下:
window.addEventListener('contextmenu',function () {alert('您好!'); })? ? ? ? ?修改demo2.html,增加引入?<script src="render/demo2.js"></script>
當我們要使用?Menu?模塊,它是主線中的模塊,如果想在渲染線程中使用,就必須使用?remote?。demo2.js 代碼如下:?
// window.addEventListener('contextmenu',function () { // alert('您好!'); // })const { remote } = require('electron')let rigthTemplate = [{label: '粘貼',accelerator: 'ctrl+v'},{label: '復制',accelerator: 'ctrl+c'} ]let m = remote.Menu.buildFromTemplate(rigthTemplate);window.addEventListener('contextmenu',function (e) {// 阻止當前窗口默認事件e.preventDefault();// 把菜單模板添加到右鍵菜單m.popup({window:remote.getCurrentWindow()}); })(3)、程序打開調試模式,運行測試
????????由于我們已經定義了頂部菜單,沒有了打開調試模式的菜單了,這時候可以使用程序來進行打開。
????????在 main.js 主進程的 ready 生命周期中加入如下這句代碼就可以了:
????????mainWindow.webContents.openDevTools()
4、Electron中通過鏈接打開瀏覽器
5、Electron中嵌入網頁和打開子窗口
6、Electron Window.open子窗口和父窗口間的通信
7、Electron選擇文件對話框
8、Electron保存對話框的操作
9、Electron消息對話框的操作
10、Electron斷網提醒功能制作
11、Electron底部通知消息的制作
12、Electron注冊全局快捷鍵
13、Electron剪貼板事件的使用
14、Electron-vue開發項目
四,Electron 項目進階
1、克隆示例項目
(1)、項目倉庫地址?
????????git clone https://github.com/electron/electron-quick-start
(2)、下載完成后進入 electron-quick-start 目錄中
?(3)、使用淘寶鏡像下載項目所需的依賴
? ? ? ?采用如下命令設置淘寶鏡像
????????????????npm? config set ELECTRON_MIRROR https://npm.taobao.org/mirrors/electron/
? ? ? ? ?采用命令 npm install 進行所需依賴安裝
?(4)、啟動工程測試
? ? ? ? 采用命令 npm start 啟動項目
2、app常用事件
?(1)、ready 當electron完成初始化時被觸發
app.on('ready',() => {console.log("*******ready******");createWindow(); })?(2)、window-all-closed 所有窗口被關閉
app.on('window-all-closed', function () {console.log("*******window-all-closed******"); })?(3)、quit 在所有應用程序退出時發出
app.on('window-all-closed', function () {if (process.platform !== 'darwin') {console.log("*******quit******");app.quit()} })(4)、open-file 在應用中要打開一個文件時發出
(5)、open-url 應用中要打開一個URL網址時發出
(6)、activate 當應用被激活時發出
3、webContents常用事件
?(1)、did-finish-load 導航完成時觸發,即選項卡的旋轉器將停止旋轉,并指派 onload 事件后
mainWindow.webContents.on('did-finish-load',()=>{console.log("did-finish-load") })?(2)、dom-ready 一個框架中的文本加載完成后觸發該事件
mainWindow.webContents.on('dom-ready',()=>{console.log("dom-ready") })4、process 進程對象
?(1)、編輯Index.html文件,如下:
<!DOCTYPE html> <html><head><meta charset="UTF-8"><meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'"><link href="./styles.css" rel="stylesheet"><title>Process</title></head><body><button id="buttonProcess" >查看Process信息</button><script src="./renderer.js"></script></body> </html>?(2)、編輯渲染進程renderer.js,定義查看進程信息
var processBtn=document.getElementById('buttonProcess');processBtn.onclick=getProcessInfo;function getProcessInfo() {console.log("getCPUUsage=",process.getCPUUsage());console.log("arch=",process.arch);console.log("platform=",process.platform);console.log("env=",process.env); }5、File對象
????????在文件系統中,使用HTML5 File 原生API操作文件
????????DOM文件接口為原生文件提供了抽象,以便讓用戶使用HTML5文件API直接處理原生文件對象。Electron已經向文件對象接口添加了一個path屬性,在文件系統中暴露出文件的真實路徑
?(1)、在index.html文件中添加文件拖動代碼
<!DOCTYPE html> <html><head><meta charset="UTF-8"><meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'"><link href="./styles.css" rel="stylesheet"><title>Process</title></head><body><div class="for_file_drag" id="drag_test"><h2>File對象</h2><span>往這里拖動文件</span></div><button id="buttonProcess" >查看Process信息</button><script src="./renderer.js"></script></body> </html>?(2)、在styles.css樣式中新增拖拽區域的樣式
.for_file_drag {width: 100%;height: 200px;background: pink; }?(4)、在renderer.js中添加如下方法
const electron = require("electron"); const fs = require('fs');const dragWrapper = document.getElementById("drag_test");dragWrapper.addEventListener('drop',(e) => {e.preventDefault();const files = e.dataTransfer.files;if(files && files.length>0){// 獲取文件路徑const path = files[0].path;console.log('path',path);// 獲取文件內容const content = fs.readFileSync(path);console.log(content.toString());} })dragWrapper.addEventListener('dragover',(e)=>{e.preventDefault(); })?(5)、測試
?
6、webview
在一個獨立的frame和進程里面顯示外部web內容
7、window.opn
8、BrowserWindowProxy
9、BrowserWindow
10、BrowserView
11、dialog
12、系統快捷鍵
13、主進程與渲染進程通信
14、原生應用菜單
15、網絡
16、集成VUE
16、E
總結
以上是生活随笔為你收集整理的Electron从入门到精通的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: YTO2736
- 下一篇: python模拟ps中的素描工具