创建新的 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 链接
在 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
文件中,将您的节点绑定名称添加到 Electron 的内置模块中。
#define ELECTRON_BROWSER_MODULES(V) \
V(electron_browser_{api_name})
注意:有关 Node 如何与 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') },
];