创建新的 Electron 浏览器模块¶
欢迎阅读 Electron API 指南!如果你不熟悉如何在 browser 目录中创建新的 Electron API 模块,本指南可作为一些必要步骤的检查清单,供你参考实现。
这并不是一份创建 Electron 浏览器 API 的全面终极指南,而是一份概述,记录了其中一些较为不直观的步骤。
将你的文件添加到 Electron 的项目配置中¶
Electron 使用 GN 作为元构建系统,为其编译器 Ninja 生成文件。这意味着,为了让 Electron 编译你的代码,我们必须在 filenames.gni 中添加你的 API 代码文件和头文件名。
你需要按字母顺序将 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 是一个用于具有相应 v8 包装对象的 C++ 对象的基类。
以下是一个基本示例,展示了你可能需要添加的代码,以便将 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::DeprecatedWrappable<ApiName> {
public:
static gin::Handle<ApiName> Create(v8::Isolate* isolate);
// gin::Wrappable
static gin::DeprecatedWrapperInfo 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::DeprecatedWrapperInfo 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* const isolate = v8::Isolate::GetCurrent();
gin_helper::Dictionary dict(isolate, exports);
dict.Set("apiName", electron::api::ApiName::Create(isolate));
}
} // namespace
将你的 Electron API 与 Node 链接¶
在 typings/internal-ambient.d.ts 文件中,我们需要向 Process 接口追加一个新属性,如下所示:
```ts title='typings/internal-ambient.d.ts' @ts-nocheck interface Process { linkedBinding(name: 'electron_browser'): Electron.ApiName; }
在你的 `api_name.cc` 文件的最底部:
```cpp title='api_name.cc'
NODE_LINKED_BINDING_CONTEXT_AWARE(electron_browser_{api_name},Initialize)
在你的 shell/common/node_bindings.cc 文件中,将你的 Node 绑定名称添加到 Electron 的内置模块中。
[!NOTE] 关于 Node 如何与 Electron 链接的更多技术细节,可以在我们的博客上找到。
向 TypeScript 公开你的 API¶
将你的 API 作为模块导出¶
我们需要在以下路径下创建一个新的 TypeScript 文件:
"lib/browser/api/{electron_browser_{api_name}}.ts"
该文件内容的示例可以在这里找到。
将模块暴露给 TypeScript¶
将你的模块添加到位于 "lib/browser/api/module-list.ts" 的模块列表中,如下所示:
ts title='lib/browser/api/module-list.ts' @ts-nocheck
export const browserModuleList: ElectronInternal.ModuleEntry[] = [
{ name: 'apiName', loader: () => require('./api-name') }
];
本页原文 Markdown:在 AtomGit 查看·内容源自开源项目 el/electron