Skip to content

electron 截屏相关概念

electron 应用你可以看作是一个 Node.js 应用,如果 electron 没有提供的 API 或者功能,那么你应该往 Node.js 去想,如果 Node.js 也没有,那么看看 C++、Rust、Python 等语言,通过 Node.js 调用 C++代码,可以解决你 99.99%的问题。

electron 是什么?

Electron 是一个使用 JavaScript、HTML 和 CSS 构建桌面应用程序的框架。 嵌入 Chromium 和 Node.js 到 二进制的 Electron 允许您保持一个 JavaScript 代码代码库并创建 在 Windows 上运行的跨平台应用 macOS 和 Linux——不需要本地开发 经验。

Node.js 简介

Node.js 是一个开源的、跨平台的 JavaScript 运行环境。它几乎适用于任何类型的项目,是一款流行的工具!

Node.js 在浏览器之外运行 V8 JavaScript 引擎,即 Google Chrome 的核心。这使得 Node.js 具有非常高的性能。

Node.js 应用程序在单个进程中运行,不会为每个请求创建新线程。Node.js 在其标准库中提供了一组异步 I/O 原语,防止 JavaScript 代码阻塞。通常,Node.js 中的库都是采用非阻塞范式编写的,使阻塞行为成为例外而非常态。

当 Node.js 执行 I/O 操作时,比如读取网络、访问数据库或文件系统,它不会阻塞线程并浪费 CPU 周期等待,而是在响应返回时继续操作。

这使得 Node.js 能够在单个服务器上处理数千个并发连接,而无需引入管理线程并发的负担,这可能是导致大量错误的原因。

Node.js 具有独特的优势,因为数以百万计为浏览器编写 JavaScript 的前端开发者现在无需学习完全不同的语言,就能编写服务器端代码。

在 Node.js 中,可以毫无问题地使用新的 ECMAScript 标准,因为你不必等待所有用户更新他们的浏览器——你可以通过更改 Node.js 的版本来决定使用哪个 ECMAScript 版本,还可以通过使用标志运行 Node.js 来启用特定的实验性功能。

Node.js Addon 是什么

Node.js Addon 是用来扩展 Node.js 功能的 本地原生扩展,它允许开发者使用 C、C++ 或 Rust 等语言编写代码,并通过与 Node.js 进行交互,将这些代码作为模块加载到 Node.js 应用程序中。

Node.js Addon 的主要作用是:

  1. 性能提升:对于某些高性能需求的任务(如计算密集型操作、硬件访问、底层系统调用等),用 C++ 等底层语言实现比用 JavaScript 更高效。通过 Node.js Addon,开发者可以将关键部分用 C/C++ 实现,从而提升整体性能。

  2. 与系统 API 交互:某些操作系统级别的 API(如文件系统、网络、硬件设备等)无法通过纯 JavaScript 直接访问,Node.js Addon 可以帮助实现与系统底层 API 的交互。

  3. 复用已有的 C/C++ 库:如果已有大量 C/C++ 编写的库或者程序逻辑,开发者可以通过 Node.js Addon 将这些库集成到 Node.js 项目中,无需完全重写。

如何编写 Node.js Addon?

开发者可以使用 C++ 来编写 Node.js Addon,通常借助两种主要工具:

  1. N-API(Node API):这是 Node.js 提供的一套稳定的 C API,开发者可以通过它编写跨版本的 Addon。N-API 保证不同版本的 Node.js 能够兼容相同的 Addon。
  2. Node.js C++ Addons:直接使用 Node.js 提供的 C++ API,可以创建高性能的 Addon,但这种方式在 Node.js 不同版本之间可能存在兼容性问题。

典型的开发步骤:

  1. 编写 C/C++ 代码:实现你想要通过 Addon 提供的功能。

  2. 使用 node-gyp 构建工具node-gyp 是 Node.js 用来编译和构建 Addon 的工具。通过它将 C/C++ 代码编译成可供 Node.js 加载的二进制模块。

  3. 在 Node.js 中加载和使用 Addon

    • 通过 require() 函数加载编译后的 Addon 模块。
    • Addon 模块表现得像普通的 JavaScript 模块,开发者可以通过调用它提供的方法进行交互。

示例:简单的 C++ Addon

以下是一个简单的 C++ Addon 示例,它暴露了一个函数,返回两数相加的结果:

cpp
#include <napi.h>

// 定义一个 C++ 函数
Napi::Number Add(const Napi::CallbackInfo& info) {
  Napi::Env env = info.Env();

  // 获取传入的参数
  double arg0 = info[0].As<Napi::Number>().DoubleValue();
  double arg1 = info[1].As<Napi::Number>().DoubleValue();

  // 返回两数相加的结果
  return Napi::Number::New(env, arg0 + arg1);
}

// 初始化 Addon
Napi::Object Init(Napi::Env env, Napi::Object exports) {
  exports.Set(Napi::String::New(env, "add"), Napi::Function::New(env, Add));
  return exports;
}

// 注册 Addon
NODE_API_MODULE(addon, Init)

然后使用 node-gyp 进行构建,在 Node.js 中加载并调用该模块:

javascript
const addon = require("./build/Release/addon");
console.log(addon.add(1, 2)); // 输出 3

应用场景:

  • 与硬件设备交互:Node.js Addon 常用于与系统中的硬件进行通信,如 USB 设备、摄像头等。
  • 性能要求高的任务:例如视频/音频处理、加密解密操作等,通常会通过 Addon 进行实现以提升性能。
  • 复用现有的 C/C++ 代码:企业或项目中已有大量的 C/C++ 代码库,想在 Node.js 项目中继续使用这些库时。

总结:

Node.js Addon 是扩展 Node.js 功能的强大工具,通过它,开发者可以将高效的 C/C++ 代码集成到 Node.js 中,满足对底层系统操作和性能要求较高的场景。

Node.js addon 与 Node.js napi 的区别

Node.js Addon 和 Node.js N-API 都是用来扩展 Node.js 功能的方式,主要用于编写本地原生扩展,尤其是通过 C、C++ 等语言编写的扩展。它们的主要区别在于实现方式兼容性,具体如下:

Node.js Addon

Node.js Addon 通常指的是直接使用 Node.js 的 V8 引擎和 C++ API 编写的原生扩展模块。这个方式能够直接访问 V8 的内部特性,适用于性能要求高的场景或与底层系统进行交互的需求。

特点:

  1. 依赖于 V8 引擎:Node.js Addon 通常使用 Node.js 和 V8 提供的 C++ API,因此和 V8 引擎的实现紧密耦合。

  2. 不跨版本兼容:由于不同版本的 Node.js 可能升级了 V8 引擎,API 可能会发生变化。因此,如果使用传统的 C++ API 编写的 Node.js Addon,在升级 Node.js 版本时,Addon 可能需要重新编写或修改代码以适应新版本的 V8 API。

  3. 高性能:直接使用 V8 的 C++ API 编写的 Addon 具有很高的性能,因为它能直接操作 V8 的内部结构并控制内存管理。

  4. 更复杂的接口:使用 Node.js 和 V8 的原生 C++ API,开发人员必须理解 V8 的对象模型和垃圾回收机制,开发门槛较高。

使用场景:

  • 当需要与底层硬件设备或系统 API 交互时。
  • 当性能至关重要,且需要直接利用 V8 的底层特性时。

N-API (Node API)

N-API 是 Node.js 提供的一组稳定的 C API,专门用于编写原生扩展模块(Node.js Addon)。它的目的是为 Node.js Addon 提供一个与 V8 引擎无关的接口,保证跨版本的二进制兼容性。

特点:

  1. 与 V8 无关的接口:N-API 提供了一套与 V8 引擎解耦的 C API,这意味着 N-API 可以在不同的 Node.js 版本中保持兼容,不受 V8 引擎升级的影响。

  2. 跨版本兼容:N-API 保证了在 Node.js 的不同版本中,使用相同的二进制模块(Addon)依然能够正常运行。这大大减少了由于 Node.js 版本变化带来的维护成本。

  3. 开发门槛更低:相比直接使用 V8 的 C++ API,N-API 提供了更加抽象的 API 层,开发者不需要深入理解 V8 的内部结构和变化,从而简化了开发流程。

  4. 稍逊的性能:由于 N-API 进行了抽象层的处理,虽然性能依然非常高,但相比直接使用 V8 C++ API 的 Node.js Addon,可能略有性能损失。

使用场景:

  • 当需要编写具有跨版本兼容性的 Addon 时。
  • 当需要减少维护成本,并且对底层性能要求不特别严格时。

总结:Node.js Addon 与 N-API 的区别

特性Node.js Addon(V8 C++ API)N-API(Node API)
依赖性直接依赖于 V8 引擎的 C++ API与 V8 引擎无关,提供稳定的 C API
版本兼容性可能在 Node.js 或 V8 升级时失效保证跨 Node.js 版本的二进制兼容性
性能性能最优,因为直接操作 V8 的底层结构性能稍逊于 V8 C++ API,但仍然高效
开发复杂度开发复杂,要求深入理解 V8 和 C++相对简单,屏蔽了 V8 的复杂性
使用场景性能和 V8 依赖性很高的应用需要跨版本兼容或开发成本较低的应用

什么时候选择 N-API?

如果你想编写的 Addon 能够在多个 Node.js 版本上运行而无需更改代码或重新编译,那么使用 N-API 是最佳选择。它的跨版本兼容性和开发便利性使得它适合大多数扩展模块开发场景。

什么时候选择传统的 Node.js Addon?

如果你对性能有非常高的要求,或者需要直接利用 V8 的一些特性(如对象结构、垃圾回收等),那么直接使用 V8 C++ API 编写的 Node.js Addon 可能会更适合。

N-API 逐渐成为推荐的方式,因为它的跨版本兼容性为开发者提供了更大的便利和灵活性。