2021-4-30

Electron 开发------------------

官页 官页 - 文档 node api 文档

Electron 是一个框架, 使您可以使用JavaScript, HTML和CSS创建桌面应用程序; 然后, 可以将这些应用程序打包以直接在macOS, Windows或Linux上运行, 或通过Mac App Store或Microsoft Store分发;

Electron 将Chromium Content Module和 Node.js 运行时整合在一起, 开发者利用electron, 可以通过web页面创建GUI界面, 同时, 通过与具体操作系统无关的API, 调用windows/macOS/Linus 原生操作系统的功能;

in short 基于 Chromium 内核渲染页面的应用, 换句话或所有网页应用都可以用Electron套个壳子, 打包成不同平台的本地应用.. 但反过来不可以, 浏览器不能识别Electron 的API

quick-start

quick-start

To check that Node.js was installed correctly, type the following commands in your terminal client:

node -v
npm -v

Create a folder for your project and install Electron there:

//mkdir my-electron-app && cd my-electron-app
npm init -y
npm i --save-dev electron

主脚本文件 main.js

Create the main script file

Create the main script file

main.js

//为了管理应用程序的生命周期事件以及创建和控制浏览器窗口, 您从 electron 包导入了 app 和 BrowserWindow 模块 ; 
const { app, BrowserWindow } = require('electron')
 
 //定义了一个创建 新的浏览窗口的函数并将 nodeIntegration设置为true(使用Node api), 将 index.html 文件加载到窗口中(第 12 行, 稍后我们将讨论该文件)
function createWindow () {
  const win = new BrowserWindow({
    width: 800,
    height: 600,
    webPreferences: {
      nodeIntegration: true
    }
  })
 
  win.loadFile('index.html')
}
//你通过调用 createWindow方法, 在 electron app 第一次被初始化时创建了一个新的窗口; 
app.whenReady().then(createWindow)
//您添加了一个新的侦听器, 当应用程序不再有任何打开窗口时试图退出;  由于操作系统的 窗口管理行为 , 此监听器在 macOS 上是禁止操作的; 
app.on('window-all-closed', () => {
  if (process.platform !== 'darwin') {
    app.quit()
  }
})
//您添加一个新的侦听器, 只有当应用程序激活后没有可见窗口时, 才能创建新的浏览器窗口;  例如, 在首次启动应用程序后或重启运行中的应用程序; 
app.on('activate', () => {
  if (BrowserWindow.getAllWindows().length === 0) {
    createWindow()
  }
})
 

要从渲染过程中访问 Node.js API, 您需要设置 nodeIntegration 选项为 true

页面 index.html

Create a web page

index.html

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Hello World!</title>
    <meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline';" />
</head>
<body style="background: white;">
    <h1>Hello World!</h1>
    <p>
        We are using node <script>document.write(process.versions.node)</script>,
        Chrome <script>document.write(process.versions.chrome)</script>,
        and Electron <script>document.write(process.versions.electron)</script>.
    </p>
</body>
</html>
 

修改 package.json

modify package.json

Modify your package.json file

您的 Electron 应用程序使用 package.json 文件作为主入口(像任何其它的 Node.js 应用程序); 您的应用程序的主脚本是 main.js, 所以相应修改 package.json 文件:

package.json

{
    "name": "my-electron-app",
    "version": "0.1.0",
    "author": "your name",
    "description": "My Electron app",
    "main": "main.js",
    "scripts": {
        "start": "electron ."
    }
}

启动 start

运行您的应用程序: npm start

错误 Electron failed to install correctly

F:\node_project\my-electron-app\node_modules\electron\index.js:14
    throw new Error('Electron failed to install correctly, please delete node_modules/electron and try installing again');in');
    ^
 
Error: Electron failed to install correctly, please delete node_modules/electron and try installing again
    at getElectronPath (F:\node_project\my-electron-app\node_modules\electron\index.js:14:11)
    at Object.<anonymous> (F:\node_project\my-electron-app\node_modules\electron\index.js:18:18)
 
 
 

关键代码: \electron\index.js:14

const fs = require('fs');
const path = require('path');
 
const pathFile = path.join(__dirname, 'path.txt');

path.txt 找不到, 安装不完整, CD到node_modules\electron 目录执行 node install.js 可reinstall生成配置..

but

C:\Users\yang\AppData\Roaming\npm\node_modules\electron>node install.js
RequestError: connect ETIMEDOUT 52.74.223.119:443
    at ClientRequest.<anonymous> (C:\Users\yang\AppData\Roaming\npm\node_modules\electron\node_modules\got\source\request-as-event-emitter.js:178:14)
    at Object.onceWrapper (events.js:418:26)
    at ClientRequest.emit (events.js:323:22)
    at ClientRequest.origin.emit (C:\Users\yang\AppData\Roaming\npm\node_modules\electron\node_modules\@szmarczak\http-timer\source\index.js:37:11)
    at TLSSocket.socketErrorListener (_http_client.js:426:9)
    at TLSSocket.emit (events.js:311:20)
    at emitErrorNT (internal/streams/destroy.js:92:8)
    at emitErrorAndCloseNT (internal/streams/destroy.js:60:3)
    at processTicksAndRejections (internal/process/task_queues.js:84:21)

52.74.223.119 是 github 的服务器… 八成因为GFW抽了.

主线程和渲染进程

main-and-renderer-processes

主进程

在 Electron 里, 有两类进程, 运行 package.json 里 main 脚本的进程被称为主进程; 在主进程运行的脚本可以创建 web 页面的形式展示 GUI; Electron 应用程序只能有一个主进程;

主进程通过创建 BrowserWindow 实例来创建网页;主进程管理所有网页及其对应的渲染进程;

Electron 主线程包含的内容(API)

  1. Chromium for displaying web content.
  2. Node.js for working with the local filesystem and the operating system.
  3. Custom APIs for working with often-needed OS native functions. 自定义API的文档

To create a window, call the BrowserWindow class, which isonly available in the Main process:

const { BrowserWindow } = require('electron')
const win = new BrowserWindow()

渲染进程

由于 Electron 使用 Chromium 来展示页面, 所以 Chromium 的多进程结构也被充分利用; 每个 Electron 的页面都在运行着自己的进程, 这样的进程我们称之为渲染进程;

  • 每个BrowserWindow实例在其Renderer进程中运行网页;每个渲染进程都是相互独立的 销毁BrowserWindow实例后, 相应的Renderer进程也将终止; 一个渲染进程的崩溃不会影响其他渲染进程;

-渲染进程通过 IPC 与主进程通信在网在页上执行 GUI 操作; 出于安全和可能的资源泄漏考虑, 直接从渲染器进程中调用与本地 GUI 有关的 API 受到限制;

渲染进程使用ipc与主进程通讯

// In the Main process
const { ipcMain } = require('electron')
 
ipcMain.handle('perform-action', (event, ...args) => {
  // ... do actions on behalf of the Renderer
})