Electron入門教程

原文連接:Electron入門教程html

Electron是由Github開發,用HTML,CSS和JavaScript來構建跨平臺桌面應用程序的一個開源庫。 Electron經過將 ChromiumNode.js合併到同一個運行時環境中,並將其打包爲Mac,Windows和Linux系統下的應用來實現這一目的。前端

相信大部分前端同窗都據說或者瞭解過NodeJs 它是一個基於Chrome V8 引擎的JavaScript運行時, 而 Chromium 是Google爲發展自家瀏覽器Chrome而開啓的開源瀏覽器項目,能夠當作是是Chrome的先行版。你們較爲熟悉的VS Code 和 Atom就是使用Electron來完成的。node

從開發的角度來看, Electron application 本質上是一個 Node. js 應用程序。可讓前端開發者讓你使用純 JavaScript 調用豐富的原生操做系統APIs來創造桌面應用~react

Quick Start

確認你的網絡能夠訪問github , 若訪問受限參考 安裝指南 來了解如何用代理、鏡像和自定義緩存git

你確定已經已經安裝好git和node了,那麼只要:github

# 官網已經有 electron-quick-start 倉庫克隆下來
git clone https://github.com/electron/electron-quick-start
# 進入文件夾
cd electron-quick-start
# 安裝依賴包並運行
npm install && npm start
複製代碼

而後你的第一個桌面應用就開啓了!web

若你跟着一塊兒實踐到這裏,確定會發現界面有些許不一樣?我這裏多了個調試界面,那麼來看下代碼看看。在Electron中main.js是入口文件:npm

//main.js
const { app, BrowserWindow } = require('electron')

// Keep a global reference of the window object, if you don't, the window will
// be closed automatically when the JavaScript object is garbage collected.
let win

function createWindow () {
  // 建立瀏覽器窗口。
  win = new BrowserWindow({ width: 800, height: 600 })

  // 而後加載應用的 index.html。對應的index.html 就是初始界面。
  win.loadFile('index.html')

  // 打開開發者工具
  win.webContents.openDevTools()

  //關於win 窗口的生命週期咱們以後再研究……
  // 當 window 被關閉,這個事件會被觸發。
  win.on('closed', () => {
    // 取消引用 window 對象,若是你的應用支持多窗口的話,
    // 一般會把多個 window 對象存放在一個數組裏面,
    // 與此同時,你應該刪除相應的元素。
    win = null
  })
}
//關於 app 主進程的生命週期咱們以後再研究……
// Electron 會在初始化後並準備
// 建立瀏覽器窗口時,調用這個函數。
// 部分 API 在 ready 事件觸發後才能使用。
app.on('ready', createWindow)

// 當所有窗口關閉時退出。
app.on('window-all-closed', () => {
  // 在 macOS 上,除非用戶用 Cmd + Q 肯定地退出,
  // 不然絕大部分應用及其菜單欄會保持激活。
  if (process.platform !== 'darwin') {
    app.quit()
  }
})

app.on('activate', () => {
  // 在macOS上,當單擊dock圖標而且沒有其餘窗口打開時,
  // 一般在應用程序中從新建立一個窗口。
  if (win === null) {
    createWindow()
  }
})

// 在這個文件中,你能夠續寫應用剩下主進程代碼。
// 也能夠拆分紅幾個文件,而後用 require 導入。

複製代碼

與現有React工程結合

迫於不會Vue ,在這裏介紹下React工程如何和Electron結合起來。json

偷懶就直接使用 create-react-app 來建立react工程:api

#若已安裝 請忽略
npm install -g create-react-app
create-react-app react-electron
cd react-electron
npm start
複製代碼

添加 Electron 配置並啓動

1、 安裝 Electron包

# 在 react-electron 目錄下安裝 Electron 包
npm install -save electron
複製代碼

2、 添加main.js

在 react-electron 目錄下添加main.js ,直接使用上面 main.js的內容 ,而後

//win.loadFile('index.html') 這一行替換爲:
win.loadFile('http://localhost:3000/')
複製代碼

這樣就將入口界面指定到react的初始界面了。

3、 啓動Electron!

修改 package.json ,添加 main homepage字段,並添加electron-start命令:

"main": "main.js",
  "homepage":".",

  "scripts": {
    "start": "react-scripts start",
    "build": "react-scriptsbuild",
    "test": "react-scripts test --env=jsdom",
    "eject": "react-scripts eject",
    "electron": "electron ."
  },
}
複製代碼

啓動 Electron:

# 啓動react項目
npm start
# 啓動electron
npm run electron
複製代碼

看到一篇 文章 CREATE AN APP WITH ELECTRON AND REACT 寫create-react-app和Electron結合的不錯,你們也能夠參考這個。

4、在react中使用electron

直接在react中使用import electron會產生問題 issues/7300,能夠寫成這種形式:

const electron = window.require('electron');
const fs = electron.remote.require('fs');
const ipcRenderer  = electron.ipcRenderer;
複製代碼

主進程和渲染進程

Electron 與web應用的區別不是很大,在原web應用的基礎上添加主線程交互代碼後,甚至能夠將一個線上web應用迅速的包裝成爲一個客戶端應用! Electron而且內集成了 Nodejs,Nodejs 在主進程和渲染進程中均可以使用,這爲咱們提供了npm成千上萬的模塊。

因此我的感受應用Electron的重要在於理解主進程和渲染進程,和進程間的交互。其餘API能夠本身花點時間閱讀文檔。

運行Electron入口文件的進程(也就是上文運行main.js的進程)被稱爲主進程,它控制着整個 App 的生命週期,從打開到關閉。 它也管理着系統原生元素好比菜單,菜單欄,Dock 欄,托盤等。 主進程負責建立 APP 的每一個渲染進程。並且整個 Node API 都集成在裏面;

而在主進程建立的一個個web頁面(對應上文中的win窗口)也都運行着本身的進程,即渲染進程,渲染進程各自獨立,各自擁有本身的生命週期。與主進程不一樣的是,它可以同時存在多個並且運行在不同的進程。並且它們也可以被隱藏。在一般的瀏覽器內,網頁一般運行在一個沙盒的環境擋住而且不可以使用原生的資源。 然而 Electron 的用戶在 Node.js 的 API 支持下能夠在頁面中和操做系統進行一些低級別的交互。

進程間通訊

Electron提供了幾種通訊方式:

一 使用ipc-rendereripc-main :

ipc-renderer 和 ipc-main 異步交互:

//在渲染進程中:
const {ipcRenderer} = require('electron')
//發送asynchronous-message事件到主進程
ipcRenderer.send('asynchronous-message', 'ping')
//接收主進程的asynchronous-reply通知
ipcRenderer.on('asynchronous-reply', (event, arg) => {
  console.log('asynchronous-reply : args:',arg)
  const message = `Asynchronous message reply: ${arg}`
  document.getElementById('async-reply').innerHTML = message
})

//在主進程中:
const {ipcMain} = require('electron')
//接收渲染進程的asynchronous-message通知
ipcMain.on('asynchronous-message', (event, arg) => {
  //發送asynchronous-reply事件到渲染進程
  event.sender.send('asynchronous-reply', {'ping':'pong','num':'1'})
})

複製代碼

ipc-renderer 和 ipc-main 同步交互:

//在渲染進程中:
const {ipcRenderer} = require('electron')

const syncMsgBtn = document.getElementById('sync-msg')

syncMsgBtn.addEventListener('click', () => {
  const reply = ipcRenderer.sendSync('synchronous-message', 'ping')
  const message = `Synchronous message reply: ${reply}`
  document.getElementById('sync-reply').innerHTML = message
})
//在主進程中:
const {ipcMain} = require('electron')

ipcMain.on('synchronous-message', (event, arg) => {
  event.returnValue = 'pong'
})

複製代碼

二 在渲染進程使用remote模塊

// 在渲染進程打開提示對話框
const {dialog} = require('electron').remote
dialog.showMessageBox(options, (index) => {
      ....
    })
複製代碼

三 在主進程向渲染進程webContents發送消息

win.webContents.send('ping', 'whoooooooh!')
複製代碼

四 渲染進程之間的通訊

在兩個網頁(渲染進程)間共享數據最簡單的方法是使用瀏覽器中已經實現的 HTML5 API。 其中比較好的方案是用 Storage API, localStorage,sessionStorage 或者 IndexedDB。

你還能夠用 Electron 內的 IPC 機制實現。將數據存在主進程的某個全局變量中,而後在多個渲染進程中使用 remote 模塊來訪問它。

// 在主進程中
global.sharedObject = {
  someProperty: 'default value'
}
// 在第一個頁面中
require('electron').remote.getGlobal('sharedObject').someProperty = 'new value'
// 在第二個頁面中
console.log(require('electron').remote.getGlobal('sharedObject').someProperty)
複製代碼
相關文章
相關標籤/搜索