Electron

electron组成

electron.png

electron由Node.js+Chromium+Native APIs构成。可以理解为,它是一个得到了Node.js和基于不同平台的Native APIs加强的Chromium浏览器,可以用来开发跨平台的桌面级应用。

主进程(mian process)

主进程,通常是值 main.js 文件,是每个 Electron 应用的入口文件。它控制着整个 App 的生命周期,从打开到关闭。 它也管理着原生元素比如菜单,菜单栏,Dock 栏,托盘等。 主进程负责创建 APP 的每个渲染进程。而且整个 Node API 都集成在里面。

每个 app 的主进程文件都定义在 package.json 中的 main 属性当中

在Chromium中, 这个进程被称为 "浏览器进程"。它在Electron被重新命名, 以避免与渲染器进程混淆。

渲染进程(renderer process)

渲染进程是应用内的一个浏览器窗口。与主进程不同的是,它能够同时存在多个而且运行在不一样的进程。而且它们也能够被隐藏。

在通常的浏览器内,网页通常运行在一个沙盒的环境挡住并且不能够使用原生的资源。 然而 Electron 的用户在 Node.js 的 API 支持下可以在页面中和操作系统进行一些低级别的交互。

主进程和渲染进程

项目工程(electron-vue)

模版

vue init simulatedgreg/electron-vue my-project

工程概览

app

生命周期钩子

  • will-finish-launching 在应用完成基本启动进程之后触发

  • ready 当electron完成初始化后触发

  • window-all-closed 所有窗口都关闭的时候触发,在windows和linux里,所有窗口都退出的时候通常是应用退出的时候

  • before-quit 退出应用之前的时候触发

  • will-quit 即将退出应用的时候触发

  • quit 应用退出的时候触发

事件钩子

  • active(仅macOS)当应用处于激活状态时

  • browser-window-created 当一个BrowserWindow被创建的时候

  • browser-window-focus 当一个BrowserWindow处于激活状态的时候

  • ...

BrowserWindow

创建窗口

new BrowserWindow([options])

//options除了可以设置窗口样式及功能,还涉及网页功能设置

事件钩子

  • closed 当窗口被关闭的时候

  • focus 当窗口被激活的时候

  • show 当窗口展示的时候

  • ...

☎️ 主进程和renderer进程的通信

ipcMain模块是EventEmitter类的一个实例。 在主进程使用时,它处理异步并且接收来自于渲染进程(网页)的同步信息。 从渲染器进程发送的消息将被发送到该模块。

  • 回复同步信息时,需要设置event.returnValue。

  • 将异步消息发送回发件人,需要使用event.sender.send(...)。

方法:

  • ipcMain.on(channel, listener)

  • ipcMain.once(channel, listener)

  • ipcMain.removeListener(channel, listener)

  • ipcMain.removeAllListeners([channel])

ipcRenderer 是一个 EventEmitter 的实例。 你可以使用它提供的一些方法从渲染进程 (web 页面) 发送同步或异步的消息到主进程。 也可以接收主进程回复的消息。

方法:

  • ipcRenderer.on(channel, listener)

  • ipcRenderer.once(channel, listener)

  • ipcRenderer.removeListener(channel, listener)

  • ipcRenderer.removeAllListeners([channel])

  • ipcRenderer.send(channel[, arg1][, arg2][, ...])

  • ipcRenderer.sendSync(channel[, arg1][, arg2][, ...])

  • ipcRenderer.sendToHost(channel[, arg1][, arg2][, ...])

在渲染进程中使用node

import os from 'os'
import fs from 'fs'
import async from 'async'
import path from 'path'

inspectAndDescribeFile(filePath, cb) {
  let result = {
    file: path.basename(filePath),
    path: filePath,
    type: ''
  }
  fs.stat(filePath, (err, stat) => {
     if(err) {
       cb(err)
     }else{
       if(stat.isFile()) {
        result.type = 'file'
       }
      if(stat.isDirectory()) {
        result.type = 'directory'
      }
      cb(err, result)
    }
  })
},

调试

1.渲染进程调试

  1. chrome devtools

  2. devtron:

    • npm install devtron --save-dev

    • 在console中执行: require('devtron').install()

2.主进程调试

chrome://inspect

VS Code

打包

electron-builder OR electron-packager

builder 是在 packager 基础上的整合版,提供开发到部署一整套,生产各个平台可以执行文件、安装程序、软件签名、自动更新。

使用electron-builder 打包

npm run build

跨平台打包:

/*package.json*/

//打包mac
node .electron-vue/build.js && electron-builder --mac

//打包win
node .electron-vue/build.js && electron-builder --win

//打包linux
node .electron-vue/build.js && electron-builder --linux

//全部打包
node .electron-vue/build.js && electron-builder --platform=all

项目迁移

  • 将原有项目src文件夹下的文件迁移至renderer目录下

⚠️ 注意事项

  1. 注意拖拽事件

  2. 路由使用hash模式 (electron在生产环境下使用的是file://协议)

  3. 跨域问题:

    mainWindow = new BrowserWindow({  
        webPreferences: {webSecurity: false},  
    })
    
    allowRunningInsecureContent Boolean 
    //(可选) -允许一个 https 页面运行 http url 里的资源,包括 JavaScript, CSS 或 plugins. 默认值为 false.
    
  4. 跨平台兼容

api平台差异

原生相关

托盘

托盘应用

Tray

let tray = new Tray(`${__static}/menubar.png`)
const contextMenu = Menu.buildFromTemplate([
    {label: 'Item1', type: 'radio', click() {dialog.showMessageBox({title: 'click', message: 'click the item', detail: 'The item has been clicked!'})}},
    {label: 'Item2', type: 'radio'},
    {label: 'Item3', type: 'radio', checked: true},
    {label: 'Item4', type: 'radio'}
  ])
 tray.setToolTip('This is an application.')
 tray.setContextMenu(contextMenu)

应用菜单

应用菜单

Menu

MenuItem

let template = [
  {label: 'item0', submenu: [{label: 'item0-0'}, {label: 'item0-1'}]},
  {label: 'item1', submenu: [{label: 'item1-0'}, {label: 'item1-1'}]},
  {label: 'item2', submenu: [{label: 'item2-0'}, {label: 'item2-1'}]},
  {label: 'item3', submenu: [{label: 'item3-0'}, {label: 'item3-1'}]},
  {label: 'item4', submenu: [{label: 'item4-0'}, {label: 'item4-1'}]}
]
 const menu = Menu.buildFromTemplate(template)
 Menu.setApplicationMenu(menu)

桌面通知

HTML5 Notification API

electron-notification

References

  1. Electron文档
  2. Electron-Vue

你可能感兴趣的:(Electron)