Electron介绍

1 Electron 快速入门

简介

Electron 可以让你使用纯 JavaScript 调用丰富的原生 APIs 来创造桌面应用。你可以把它看作是专注于桌面应用而不是 web 服务器的,io.js 的一个变体。

这不意味着 Electron 是绑定了 GUI 库的 JavaScript。相反,Electron 使用 web 页面作为它的 GUI,所以你能把它看作成一个被 JavaScript 控制的,精简版的 Chromium 浏览器。

应用的入口

在 Electron 中,入口是一个 JavaScript 脚本。不同于直接提供一个URL,你需要手动创建一个浏览器窗口,然后通过 API 加载 HTML 文件。你还可以监听窗口事件,决定何时让应用退出。

主进程

在 Electron 里,运行 package.json 里 main 脚本的进程被称为主进程。在主进程运行的脚本可以以创建 web 页面的形式展示 GUI。

渲染进程

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

在一般浏览器中,网页通常会在沙盒环境下运行,并且不允许访问原生资源。然而,Electron 用户拥有在网页中调用 io.js 的 APIs 的能力,可以与底层操作系统直接交互。

主进程与渲染进程的区别

主进程使用 BrowserWindow 实例创建网页。每个 BrowserWindow 实例都在自己的渲染进程里运行着一个网页。当一个 BrowserWindow 实例被销毁后,相应的渲染进程也会被终止。

主进程管理所有页面和与之对应的渲染进程。每个渲染进程都是相互独立的,并且只关心他们自己的网页。

由于在网页里管理原生 GUI 资源是非常危险而且容易造成资源泄露,所以在网页面调用 GUI 相关的 APIs 是不被允许的。如果你想在网页里使用 GUI 操作,其对应的渲染进程必须与主进程进行通讯,请求主进程进行相关的 GUI 操作。

在 Electron,我们提供用于在主进程与渲染进程之间通讯的 ipc 模块。并且也有一个远程进程调用风格的通讯模块 remote

 Electron 中的两种进程通信方式,分别为:

  • 使用 ipcMain 和 ipcRenderer 两个模块
  • 使用 remote 模块

相比于使用两个 IPC 模块,使用 remote 模块相对来说会比较自然一点。remote 模块帮我们屏蔽了内部的进程通信,使得我们在调用主进程的方法时完全没有感知到主进程的存在。

对于remote 的实现,它底层依旧是通过 ipc 模块来实现通信:

通过 remote 对象,我们可以不必发送进程间消息来进行通信。但实际上,我们在调用远程对象的方法、函数或者通过远程构造函数创建一个新的对象,实际上都是在发送一个同步的进程间消息(官方文档 上说这类似于 JAVA 中的 RMI)。

也就是说,remote 方法只是不用让我们显式的写发送进程间的消息的方法而已。在上面通过 remote 模块创建 BrowserWindow的例子里。我们在渲染进程中创建的 BrowserWindow对象其实并不在我们的渲染进程中,它只是让主进程创建了一个 BrowserWindow对象,并返回了这个相对应的远程对象给了渲染进程。

打造你第一个 Electron 应用

大体上,一个 Electron 应用的目录结构如下:

your-app/
├── package.json
├── main.js
└── index.html

package.json的格式和 Node 的完全一致,并且那个被 main 字段声明的脚本文件是你的应用的启动脚本,它运行在主进程上。你应用里的 package.json 看起来应该像:

{
  "name"    : "your-app",
  "version" : "0.1.0",
  "main"    : "main.js"
}

注意:如果 main 字段没有在 package.json 声明,Electron会优先加载 index.js

main.js 应该用于创建窗口和处理系统时间,一个典型的例子如下:

var app = require('app');  // 控制应用生命周期的模块。
var BrowserWindow = require('browser-window');  // 创建原生浏览器窗口的模块

// 保持一个对于 window 对象的全局引用,不然,当 JavaScript 被 GC,
// window 会被自动地关闭
var mainWindow = null;

// 当所有窗口被关闭了,退出。
app.on('window-all-closed', function() {
  // 在 OS X 上,通常用户在明确地按下 Cmd + Q 之前
  // 应用会保持活动状态
  if (process.platform != 'darwin') {
    app.quit();
  }
});

// 当 Electron 完成了初始化并且准备创建浏览器窗口的时候
// 这个方法就被调用
app.on('ready', function() {
  // 创建浏览器窗口。
  mainWindow = new BrowserWindow({width: 800, height: 600});

  // 加载应用的 index.html
  mainWindow.loadURL('file://' + __dirname + '/index.html');

  // 打开开发工具
  mainWindow.openDevTools();

  // 当 window 被关闭,这个事件会被发出
  mainWindow.on('closed', function() {
    // 取消引用 window 对象,如果你的应用支持多窗口的话,
    // 通常会把多个 window 对象存放在一个数组里面,
    // 但这次不是。
    mainWindow = null;
  });
});

最后,你想展示的 index.html :

<!DOCTYPE html>
<html>
  <head>
    <title>Hello World!</title>
  </head>
  <body>
    <h1>Hello World!</h1>
    We are using io.js <script>document.write(process.version)</script>
    and Electron <script>document.write(process.versions['electron'])</script>.
  </body>
</html>

运行你的应用

一旦你创建了 main.js, index.html 和 package.json 这几个文件,你可能会想尝试在本地运行并测试,看看是不是正常运行。

如果你已经用 npm 全局安装了 electron-prebuilt,你只需要按照如下方式直接运行你的应用:

electron .

如果你是局部安装,那运行:

./node_modules/.bin/electron .

 

 

2 Electron 桌面环境集成

1.增加一个文件到最近文件列表:

var app = require('app');

app.addRecentDocument('/Users/USERNAME/Desktop/work.type');

清空最近文件列表:

app.clearRecentDocuments();

 

Windows 需注意

为了这个特性在 Windows 上表现正常,你的应用需要被注册成为一种文件类型的句柄,否则,在你注册之前,文件不会出现在跳转列表。你可以在 Application Registration 里找到任何关于注册事宜的说明。

 

2.给一个窗口设置进度条:

var window = new BrowserWindow({...});

window.setProgressBar(0.5);

 

3.Electron 在线/离线事件探测

使用标准 HTML5 APIs 可以实现在线和离线事件的探测

 

4.Electron 进程

Electron 中的 process 对象 与 upstream node 中的有以下的不同点:

  • process.type String - 进程类型, 可以是 browser (i.e. main process)或 renderer.
  • process.versions['electron'] String - Electron的版本.
  • process.versions['chrome'] String - Chromium的版本.
  • process.resourcesPath String - JavaScript源代码路径.
  • process.mas Boolean - 在Mac App Store 创建, 它的值为 true, 在其它的地方值为 undefined.

 

事件: 'loaded'

在Electron已经加载了其内部预置脚本和它准备加载主进程或渲染进程的时候触发.

当node被完全关闭的时候,它可以被预加载脚本使用来添加(原文: removed)与node无关的全局符号来回退到全局范围

 

方法

process 对象有如下方法:

process.hang()

使当前进程的主线程挂起.

 

如何在两个网页(渲染进程)间共享数据?

在两个网页(渲染进程)间共享数据最简单的方法是使用浏览器中已经实现的 HTML5 API,比较好的方案是用 Storage API, localStoragesessionStorage 或者 IndexedDB

你还可以用 Electron 内的 IPC 机制实现。将数据存在主进程的某个全局变量中,然后在多个渲染进程中使用 remote 模块来访问它。

// 在主进程中
global.sharedObject = {
  someProperty: 'default value'
};
// 在第一个页面中
require('remote').getGlobal('sharedObject').someProperty = 'new value';
// 在第二个页面中
console.log(require('remote').getGlobal('sharedObject').someProperty);

5.Electron 环境变量部分

ELECTRON_RUN_AS_NODE

类似node.js普通进程启动方式.

ELECTRON_ENABLE_LOGGING

打印 Chrome 的内部日志到控制台.

ELECTRON_LOG_ASAR_READS

当 Electron 读取 ASAR 文档,把 read offset 和文档路径做日志记录到系统 tmpdir.结果文件将提供给 ASAR 模块来优化文档组织.

ELECTRON_ENABLE_STACK_DUMPING

当 Electron 崩溃的时候,打印堆栈记录到控制台.

如果 crashReporter 已经启动那么这个环境变量实效.

ELECTRON_DEFAULT_ERROR_MODE Windows

当 Electron 崩溃的时候,显示windows的崩溃对话框.

如果 crashReporter 已经启动那么这个环境变量实效.

ELECTRON_NO_ATTACH_CONSOLE Windows

不可使用当前控制台.

ELECTRON_HIDE_INTERNAL_MODULES

关闭旧的内置模块如 require('ipc') 的通用模块.

6.Electron 支持的平台

以下的平台是 Electron 目前支持的:

OS X

对于 OS X 系统仅有64位的二进制文档,支持的最低版本是 OS X 10.8。

Windows

仅支持 Windows 7 及其以后的版本,之前的版本中是不能工作的。

对于 Windows 提供 x86 和 amd64 (x64) 版本的二进制文件。需要注意的是ARM 版本的 Windows 目前尚不支持.

Linux

预编译的 ia32(i686) 和 x64(amd64) 版本 Electron 二进制文件都是在Ubuntu 12.04 下编译的,arm 版的二进制文件是在 ARM v7(硬浮点 ABI 与Debian Wheezy 版本的 NEON)下完成的。

预编译二进制文件是否能够运行,取决于其中是否包括了编译平台链接的库,所以只有 Ubuntu 12.04可以保证正常工作,但是以下的平台也被证实可以运行 Electron 的预编译版本:

  • Ubuntu 12.04 及更新
  • Fedora 21
  • Debian 8

7.Electron 应用部署

为了使用 Electron 部署你的应用程序,你存放应用程序的文件夹需要叫做 app 并且需要放在 Electron 的资源文件夹下(在 OS X 中是指 Electron.app/Contents/Resources/,在 Linux 和 Windows 中是指 resources/)就像这样:

在 OS X 中:

electron/Electron.app/Contents/Resources/app/

├── package.json

├── main.js

└── index.html

在 Windows 和 Linux 中:

electron/resources/app

├── package.json

├── main.js

└── index.html

然后运行 Electron.app (或者 Linux 中的 electron,Windows 中的 electron.exe),接着 Electron 就会以你的应用程序的方式启动。electron 文件夹将被部署并可以分发给最终的使用者。

将你的应用程序打包成一个文件

除了通过拷贝所有的资源文件来分发你的应用程序之外,你可以可以通过打包你的应用程序为一个 asar 库文件以避免暴露你的源代码。

为了使用一个 asar 库文件代替 app 文件夹,你需要修改这个库文件的名字为 app.asar ,然后将其放到 Electron 的资源文件夹下,然后 Electron 就会试图读取这个库文件并从中启动。如下所示:

在 OS X 中:

electron/Electron.app/Contents/Resources/

└── app.asar

在 Windows 和 Linux 中:

electron/resources/

└── app.asar

8.如何安装原生模块

如下三种方法教你安装原生模块:

最简单方式

最简单的方式就是通过 electron-rebuild 包重新编译原生模块,它帮你自动完成了下载 headers、编译原生模块等步骤:

npm install --save-dev electron-rebuild

# 每次运行"npm install"时,也运行这条命令

./node_modules/.bin/electron-rebuild

# 在windows下如果上述命令遇到了问题,尝试这个:

.\node_modules\.bin\electron-rebuild.cmd

通过 npm 安装

你当然也可以通过 npm 安装原生模块。大部分步骤和安装普通模块时一样,除了以下一些系统环境变量你需要自己操作:

export npm_config_disturl=https://atom.io/download/atom-shellexport npm_config_target=0.33.1export npm_config_arch=x64export npm_config_runtime=electron

HOME=~/.electron-gyp npm install module-name

通过 node-gyp 安装

你需要告诉 node-gyp 去哪下载 Electron 的 headers,以及下载什么版本:

$ cd /path-to-module/

$ HOME=~/.electron-gyp node-gyp rebuild --target=0.29.1 --arch=x64 --dist-url=https://atom.io/download/atom-shell

HOME=~/.electron-gyp 设置去哪找开发时的 headers。

--target=0.29.1 设置了 Electron 的版本

--dist-url=... 设置了 Electron 的 headers 的下载地址

--arch=x64 设置了该模块为适配64位操作系统而编译

9.Electron 术语表

ASAR

ASAR 代表了 Atom Shell Archive Format。一个 asar 压缩包就是一个简单的 tar 文件-就像将那些有联系的文件格式化至一个单独的文件中。Electron 能够任意读取其中的文件并且不需要解压缩整个文件。

ASAR 格式主要是为了提升 Windows 平台上的性能。TODO

Brightray

Brightray 是能够简单的将 libchromiumcontent 应用到应用中的一个静态库。它是专门开发给 Electron 使用,但是也能够使用在那些没有基于 Electron 的原生应用来启用 Chromium 的渲染引擎。

Brightray 是 Electron 中的一个低级别的依赖,大部分的 Electron 用户不用关心它。

DMG

是指在 macOS 上使用的苹果系统的磁盘镜像打包格式。DMG 文件通常被用来分发应用的 "installers"(安装包)。electron-builder 支持使用 dmg 来作为编译目标。

IPC

IPC 代表 Inter-Process Communication。Electron 使用 IPC 来在 [主进程] 和 [渲染进程] 之间传递 JSON 信息。

libchromiumcontent

一个单独的开源库,包含了 Chromium 的模块以及全部依赖(比如 Blink, V8 等)。

main process

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

每个 app 的主进程文件都定义在 package.json 中的 main 属性当中,这也是为什么 electron . 能够知道应该使用哪个文件来启动。

MAS

是指苹果系统上的 Mac App Store 的缩略词。有关于如何提交你的 app 至 MAS ,详见 Mac App Store Submission Guide 。

native modules

原生模块 (在 Node.js 里也叫 addons),是一些使用 C or C++ 编写的能够在 Node.js 中加载或者在 Electron 中使用 require() 方法来加载的模块,它使用起来就如同 Node.js 的模块。它主要用于桥接在 JavaScript 上运行 Node.js 和 C/C++ 的库。

Electron 支持了原生的 Node 模块,但是 Electron 非常可能安装一个不一样的 V8 引擎通过 Node 二进制编码,所以在打包原生模块的时候你需要在 指定具体的 Electron 本地头文件。

NSIS

Nullsoft Scriptable Install System 是一个微软 Windows 平台上的脚本驱动的安装制作工具。它发布在免费软件许可证书下,是一个被广泛使用的替代商业专利产品类似于 InstallShield。electron-builder 支持使用 NSIS 作为编译目标。

process

一个进程是计算机程序执行中的一个实例。Electron 应用同时使用了 main (主进程) 和一个或者多个 renderer (渲染进程)来运行多个程序。

在 Node.js 和 Electron 里面,每个运行的进程包含一个 process 对象。这个对象作为一个全局的提供当前进程的相关信息,操作方法。作为一个全局变量,它在应用内能够不用 require() 来随时取到。

renderer process

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

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

Squirrel

Squirrel 是一个开源的框架来让 Electron 的应用能够自动的更新到发布的新的版本。详见 autoUpdater API 了解如何开始使用 Squirrel。

userland

"userland" 或者 "userspace" 术语起源于 Unix 社区,当程序运行在操作系统内核之外。最近这个术语被推广在 Node 和 npm 社区用于区分 "Node core" 与发布的包的功能,对于在 npm 上注册的广大 "user(用户)" 们。

就像 Node ,Electron 致力于使用一些少量的设置和 API 来提供所有的必须的支持给开发中的跨平台应用。这个设计理念让 Electron 能够保持灵活而不被过多的规定有关于如何应该被使用。Userland 让用户能够创造和分享一些工具来提额外的功能在这个能够使用的 "core(核心)"之上。

V8

V8 是谷歌公司的开源的 JavaScript 引擎。它使用 C++ 编写并使用在谷歌公司开源的的浏览器 Google Chrome 上。V8 能够单独运行或者集成在任何一个 C++ 应用内。

webview

webview 标签用于集成 'guest(访客)' 内容(比如外部的网页)在你的 Electron 应用内。它们类似于 iframe,但是不同的是每个 webview 运行在独立的进程中。 作为页面它拥有不一样的权限并且所有的嵌入的内容和你应用之间的交互都将是异步的。这将保证你的应用对于嵌入的内容的安全性。

10.Electron 源码目录结构

源代码的结构

其他目录的结构

  • script - 用于诸如构建、打包、测试等开发用途的脚本
  • tools - 在 gyp 文件中用到的工具脚本,但与 script 目录不同, 该目录中的脚本不应该被用户直接调用
  • vendor - 第三方依赖项的源代码,为了防止人们将它与 Chromium 源码中的同名目录相混淆, 在这里我们不使用 third_party 作为目录名
  • node_modules - 在构建中用到的第三方 node 模块
  • out - ninja 的临时输出目录
  • dist - 由脚本 script/create-dist.py 创建的临时发布目录
  • external_binaries - 下载的不支持通过 gyp 构建的预编译第三方框架

 

猜你喜欢

转载自blog.csdn.net/weixin_42762089/article/details/85294367
今日推荐