跳至主要內容

建立新的 Electron 瀏覽器模組

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

這不是建立 Electron 瀏覽器 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 檔案中,將您的節點繫結名稱新增至 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') },
];