Crear un nuevo módulo de navegador Electron
¡Bienvenido a la guía de Electron API! Si no está familiarizado con la creación de un nuevo módulo de Electron API dentro del directorio browser
, esta guía sirve como una lista de verificación para algunos de los pasos necesarios que necesitará implementar.
Esta no es una guía completa para crear un Electron Browser API, sino un esquema que documenta algunos de los pasos menos intuitivos.
Añade tus archivos a la configuración del proyecto de Electron
Electron usa GN como un sistema de meta build para generar archivos para su compilador, Ninja. Esto significa que para decirle a Electron que compile su código, tenemos que añadir el código de tu API y los nombres de archivo de cabecera en filenames.gni
.
Necesitarás añadir tus nombres de archivo API alfabéticamente a los archivos apropiados así:
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",
]
Tenga en cuenta que las adiciones de las matrices de Windows, macOS y Linux son opcionales y sólo deben ser añadidas si su API tiene implementaciones específicas de la plataforma.
Crear documentación de la API
Las definiciones de tipo son generadas por Electron usando @electron/docs-parser
y @electron/typescript-definitions
. Este paso es necesario para asegurar la consistencia en toda la documentación de la API de Electron. Esto significa que para que su definición de tipo API aparezca en el archivo electron.d.ts
, debemos crear un archivo .md
. Los ejemplos se pueden encontrar en esta carpeta.
Configurar ObjectTemplateBuilder
y Wrappable
Electron construye sus módulos usando object_template_builder
.
wrappable
es una clase base para objetos C++ que tienen objetos envoltorios v8 correspondientes.
Este es un ejemplo básico de código que puede necesitar añadir para incorporar object_template_builder
y wrappable
en su API. Para más referencia, puede encontrar más implementaciones aquí.
En su archivo 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
En su archivo 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
Vincula su API de Electron con Node
En el archivo typings/internal-ambient.d.ts
, necesitamos añadir una nueva propiedad a la interfaz Process
así:
interface Process {
_linkedBinding(name: 'electron_browser_{api_name}'): Electron.ApiName;
}
En la parte final de su archivo api_name.cc
:
NODE_LINKED_BINDING_CONTEXT_AWARE(electron_browser_{api_name},Initialize)
En su archivo shell/common/node_bindings.cc
, agregue el nombre del enlace de nodos a los módulos integrados de Electron.
#define ELECTRON_BROWSER_MODULES(V) \
V(electron_browser_{api_name})
Nota: Más detalles técnicos sobre cómo vincular Node con Electron pueden encontrarse en nuestro blog.
Exponga su API a TypeScript
Exportar su API como módulo
Necesitaremos crear un nuevo archivo TypeScript en la ruta que sigue:
"lib/browser/api/{electron_browser_{api_name}}.ts"
Se puede encontrar un ejemplo de los contenidos de este archivo aquí.
Exponer su módulo a TypeScript
Añade su módulo a la lista de módulos encontrada en "lib/browser/api/module-list.ts"
así:
export const browserModuleList: ElectronInternal.ModuleEntry[] = [
{ name: 'apiName', loader: () => require('./api-name') },
];