创建新的 Electron 浏览器模块
欢迎阅读 Electron API 指南!如果您不熟悉在 browser
目录中创建新的 Electron API 模块,本指南将为您提供一些您需要实现的必要步骤的清单。
这并不是一个关于创建 Electron 浏览器 API 的全面详尽的指南,而是一个记录了一些不太直观的步骤的概述。
将您的文件添加到 Electron 的项目配置中
Electron 使用 GN 作为元构建系统来为编译器 Ninja 生成文件。这意味着,为了让 Electron 编译您的代码,我们必须将您的 API 的代码和头文件名添加到 filenames.gni
中。
您需要按字母顺序将您的 API 文件名附加到相应的文件中,如下所示
lib_sources = [
"path/to/api/api_name.cc",
"path/to/api/api_name.h",
]
lib_sources_mac = [
"path/to/api/api_name_mac.h",
"path/to/api/api_name_mac.mm",
]
lib_sources_win = [
"path/to/api/api_name_win.cc",
"path/to/api/api_name_win.h",
]
lib_sources_linux = [
"path/to/api/api_name_linux.cc",
"path/to/api/api_name_linux.h",
]
请注意,Windows、macOS 和 Linux 的数组添加是可选的,只有当您的 API 有特定的平台实现时才应添加。
创建 API 文档
类型定义由 Electron 使用 @electron/docs-parser
和 @electron/typescript-definitions
生成。此步骤对于确保 Electron API 文档的一致性是必需的。这意味着,为了让您的 API 类型定义出现在 electron.d.ts
文件中,我们必须创建一个 .md
文件。您可以在 此文件夹 中找到示例。
设置 ObjectTemplateBuilder
和 Wrappable
Electron 使用 object_template_builder
构建其模块。
Wrappable
是 C++ 对象的一个基类,它具有相应的 v8 包装器对象。
以下是您可能需要添加的代码的一个基本示例,以便将 object_template_builder
和 wrappable
整合到您的 API 中。有关更多参考,您可以在 此处 找到更多实现。
在您的 api_name.h
文件中
#ifndef ELECTRON_SHELL_BROWSER_API_ELECTRON_API_{API_NAME}_H_
#define ELECTRON_SHELL_BROWSER_API_ELECTRON_API_{API_NAME}_H_
#include "gin/handle.h"
#include "gin/wrappable.h"
namespace electron {
namespace api {
class ApiName : public gin::Wrappable<ApiName> {
public:
static gin::Handle<ApiName> Create(v8::Isolate* isolate);
// gin::Wrappable
static gin::WrapperInfo kWrapperInfo;
gin::ObjectTemplateBuilder GetObjectTemplateBuilder(
v8::Isolate* isolate) override;
const char* GetTypeName() override;
} // namespace api
} // namespace electron
在您的 api_name.cc
文件中
#include "shell/browser/api/electron_api_safe_storage.h"
#include "shell/browser/browser.h"
#include "shell/common/gin_converters/base_converter.h"
#include "shell/common/gin_converters/callback_converter.h"
#include "shell/common/gin_helper/dictionary.h"
#include "shell/common/gin_helper/object_template_builder.h"
#include "shell/common/node_includes.h"
#include "shell/common/platform_util.h"
namespace electron {
namespace api {
gin::WrapperInfo ApiName::kWrapperInfo = {gin::kEmbedderNativeGin};
gin::ObjectTemplateBuilder ApiName::GetObjectTemplateBuilder(
v8::Isolate* isolate) {
return gin::ObjectTemplateBuilder(isolate)
.SetMethod("methodName", &ApiName::methodName);
}
const char* ApiName::GetTypeName() {
return "ApiName";
}
// static
gin::Handle<ApiName> ApiName::Create(v8::Isolate* isolate) {
return gin::CreateHandle(isolate, new ApiName());
}
} // namespace api
} // namespace electron
namespace {
void Initialize(v8::Local<v8::Object> exports,
v8::Local<v8::Value> unused,
v8::Local<v8::Context> context,
void* priv) {
v8::Isolate* isolate = context->GetIsolate();
gin_helper::Dictionary dict(isolate, exports);
dict.Set("apiName", electron::api::ApiName::Create(isolate));
}
} // namespace
将您的 Electron API 与 Node.js 链接
在 typings/internal-ambient.d.ts
文件中,我们需要像这样向 Process
接口添加一个新属性
interface Process {
_linkedBinding(name: 'electron_browser_{api_name}'): Electron.ApiName;
}
在您的 api_name.cc
文件最底部
NODE_LINKED_BINDING_CONTEXT_AWARE(electron_browser_{api_name},Initialize)
在您的 shell/common/node_bindings.cc
文件中,将您的 Node.js 绑定名称添加到 Electron 的内置模块中。
#define ELECTRON_BROWSER_MODULES(V) \
V(electron_browser_{api_name})
有关 Node.js 如何与 Electron 链接的更多技术细节,请参阅 我们的博客。
将您的 API 暴露给 TypeScript
将您的 API 导出为模块
我们需要在以下路径创建一个新的 TypeScript 文件
"lib/browser/api/{electron_browser_{api_name}}.ts"
您可以在 此处 找到该文件内容的示例。
将您的模块暴露给 TypeScript
将您的模块添加到位于 "lib/browser/api/module-list.ts"
的模块列表中,如下所示
export const browserModuleList: ElectronInternal.ModuleEntry[] = [
{ name: 'apiName', loader: () => require('./api-name') },
];