今天經過技術核心、發展歷程、經常使用模塊三部份內容簡單的介紹一下Electron的身世。前端
使用 JavaScript,HTML 和 CSS 構建跨平臺的桌面應用程序的開源架構git
macOS: 僅提供64位版本,而且只支持 macOS 10.10 (Yosemite) 以及更高版本。github
Windows: 僅支持 Windows 7 或更高版本, 舊版操做系統已再也不支持(而且沒法運行),提供了 ia32 (x86) 和 x64 (amd64) 兩種二進制版本。web
Linux:支持 Ubuntu 12.0四、Fedora 2一、Debian 8 及以上版本。Electron 的 ia32 (i686) 和 x64 (amd64) 預編譯版本均是在Ubuntu 12.04 下編譯的。chrome
Electron 中的 main.js 文件進程被稱爲主進程,在主進程中運行的腳本經過建立web頁面來展現用戶界面。一個 Electron 應用老是有且只有一個主進程。api
因爲 Electron 使用了 Chromium 來展現 web 頁面,因此 Chromium 的多進程架構也被使用到。 每一個 Electron 中的 web 頁面叫作渲染進程。瀏覽器
在普通的瀏覽器中,web頁面一般在沙盒環境中運行,而且沒法訪問操做系統的原生資源。 然而 Electron 的用戶在 Node.js 的 API 支持下能夠在頁面中和操做系統進行一些底層交互。markdown
主進程使用 BrowserWindow 實例建立頁面。 每一個 BrowserWindow 實例都在本身的渲染進程裏運行頁面。 當一個 BrowserWindow 實例被銷燬後,相應的渲染進程也會被終止。架構
主進程管理全部的web頁面和它們對應的渲染進程。 每一個渲染進程都是獨立的,它只關心它所運行的 web 頁面。app
在頁面中調用與 GUI 相關的原生 API 是不被容許的,由於在 web 頁面裏操做原生的 GUI 資源是很是危險的,並且容易形成資源泄露。 若是你想在 web 頁面裏使用 GUI 操做,其對應的渲染進程必須與主進程進行通信,請求主進程進行相關的 GUI 操做。
// 渲染進程 const { ipcRenderer } = require('electron') ipcRenderer.sendSync('synchronous-message', 'ping') // 主進程 const { ipcMain } = require('electron') ipcMain.on('synchronous-message', (event, arg) => { console.log(arg) event.returnValue = 'pong' }) 複製代碼
// 渲染進程 const { ipcRenderer } = require('electron') ipcRenderer.send('asynchronous-message', '我須要建立一個新窗口') // 主進程 const { ipcMain } = require('electron') ipcMain.on('asynchronous-message', (event, arg) => { console.log(arg) event.reply('asynchronous-reply', '好的,知道了') }) // 渲染進程 ipcRenderer.on('asynchronous-reply', (event, arg) => { console.log('謝謝'); }) 複製代碼
const { app } = require('electron') app.on('window-all-closed', () => { app.quit() }) 複製代碼
const { BrowserWindow } = require('electron') let win = new BrowserWindow({ width: 800, height: 600 }) win.on('closed', () => { win = null }) win.loadURL('https://github.com') 複製代碼
const { dialog } = require('electron') dialog.showMessageBox(mainWindow, { type: 'info', defaultId: 0, message: '您是否肯定如今退出?', buttons: ['退出','取消'] }) 複製代碼
const { Menu, MenuItem } = require('electron') const menu = new Menu() menu.append(new MenuItem({ label: 'MenuItem1', click() { console.log('item 1 clicked') } })) menu.append(new MenuItem({ type: 'separator' })) menu.append(new MenuItem({ label: 'MenuItem2', type: 'checkbox', checked: true })) 複製代碼
// In the renderer process. const { desktopCapturer } = require('electron') desktopCapturer.getSources({ types: ['window', 'screen'] }).then(async sources => { for (const source of sources) { if (source.name === 'Electron') { try { const stream = await navigator.mediaDevices.getUserMedia({ audio: false, video: { mandatory: { chromeMediaSource: 'desktop', chromeMediaSourceId: source.id, minWidth: 1280, maxWidth: 1280, minHeight: 720, maxHeight: 720 } } }) handleStream(stream) } catch (e) { handleError(e) } return } } }) function handleStream (stream) { const video = document.querySelector('video') video.srcObject = stream video.onloadedmetadata = (e) => video.play() } function handleError (e) { console.log(e) } 複製代碼
const { clipboard } = require('electron') clipboard.writeText('hello i am a bit of text!') const text = clipboard.readText() console.log(text) // hello i am a bit of text!' 複製代碼