跳到主要內容

建立新的 Electron 瀏覽器模組

歡迎來到 Electron API 指南!如果您不熟悉在 browser 目錄中建立新的 Electron API 模組,本指南將作為您需要實作之必要步驟的檢查清單。

這並非建立 Electron Browser API 的完整最終指南,而是一個概述,記錄了一些較不直觀的步驟。

將您的檔案新增至 Electron 的專案設定

Electron 使用 GN 作為元建置系統,為其編譯器 Ninja 產生檔案。這表示為了告訴 Electron 編譯您的程式碼,我們必須將您的 API 程式碼和標頭檔名稱新增到 filenames.gni 中。

您需要按字母順序將您的 API 檔案名稱附加到適當的檔案中,如下所示

filenames.gni
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 檔案。範例可以在此資料夾中找到。

設定 ObjectTemplateBuilderWrappable

Electron 使用 object_template_builder 建構其模組。

wrappable 是 C++ 物件的基底類別,這些物件具有對應的 v8 包裝器物件。

以下是您可能需要加入的程式碼基本範例,以便將 object_template_builderwrappable 整合到您的 API 中。如需更多參考,您可以在這裡找到更多實作。

在您的 api_name.h 檔案中

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 檔案中

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

typings/internal-ambient.d.ts 檔案中,我們需要在 Process 介面上附加一個新的屬性,如下所示

typings/internal-ambient.d.ts
interface Process {
_linkedBinding(name: 'electron_browser_{api_name}'): Electron.ApiName;
}

在您的 api_name.cc 檔案的最底部

api_name.cc
NODE_LINKED_BINDING_CONTEXT_AWARE(electron_browser_{api_name},Initialize)

在您的 shell/common/node_bindings.cc 檔案中,將您的 Node 綁定名稱新增至 Electron 的內建模組。

shell/common/node_bindings.cc
#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" 中的模組清單,如下所示

lib/browser/api/module-list.ts
export const browserModuleList: ElectronInternal.ModuleEntry[] = [
{ name: 'apiName', loader: () => require('./api-name') },
];