Création d'un nouveau module Browser pour Electron
Bienvenue dans le guide de l'API Electron ! Si vous n'êtes pas familiarisé avec la création de nouveau module API Electron dans le répertoire browser
, ce guide vous servira de checklist pour certaines des étapes nécessaires à mettre en œuvre.
Il ne s'agit pas d'un guide complet pour créer une API de navigateur d''Electron, mais plutôt d'un aperçu documentant certaines des étapes les moins intuitives.
Ajout de vos fichiers à la configuration du projet Electron
Electron utilise GN comme méta système de compilation pour générer des fichiers pour son compilateur, Ninja. Cela signifie que pour ordonner à Electron de compiler du code, nous devons ajouter ce code de votre API et les noms des fichiers d'en-tête dans filenames.gni
.
Vous devez ajouter les noms de fichiers de votre API par ordre alphabétique dans les fichiers appropriés comme suit:
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",
]
Notez que l'ajout des tableaux Windows, macOS et Linux est facultatif et ceux-ci ne doivent être ajoutés que si votre API a des implémentations spécifiques à certaines plate-formes.
Création de la documentation de l'API
Les définitions de types sont générées par Electron en utilisant @electron/docs-parser
et @electron/typescript-definitions
. Cette étape est nécessaire pour assurer la cohérence de la documentation de l'API d'Electron. Cela signifie que pour que la définition du type de votre API apparaisse dans le fichier electron.d.ts
, un fichier .md
doit être créé. On peut trouver des exemples dans ce dossier.
Configuration de ObjectTemplateBuilder
et de Wrappable
Electron batit ses modules en utilisant object_template_builder
.
wrappable
est une classe de base pour les objets C++ qui ont des objets wrapper v8 correspondants.
Voici un exemple basique de code que vous aurez besoin d'ajouter, afin d'incorporer object_template_builder
et wrappable
dans votre API. Pour plus d'information, vous pouvez trouver d'avantage d'implémentations ici.
Dans votre fichier 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
Dans votre fichier 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
Liaison de votre API Electron avec Node
Dans le fichier typings/internal-ambient.d.ts
, nous allons devoir ajouter une nouvelle propriété à l'interface Process
de la manière suivante:
interface Process {
_linkedBinding(name: 'electron_browser_{api_name}'): Electron.ApiName;
}
Et en bas de votre fichier api_name.cc
:
NODE_LINKED_BINDING_CONTEXT_AWARE(electron_browser_{api_name},Initialize)
Dans votre fichier shell/common/node_bindings.cc
, ajouter ensuite votre nom de liaison Node aux modules intégrés d’Electron.
#define ELECTRON_BROWSER_MODULES(V) \
V(electron_browser_{api_name})
Remarque : Plus de détails techniques sur la façon dont Node est lié avec Electron peuvent être trouvés sur notre blog.
Exposition de votre API à TypeScript
Export de votre API en tant que module
Nous devons créer un nouveau fichier TypeScript dans le chemin suivant :
"lib/browser/api/{electron_browser_{api_name}}.ts"
Un exemple de contenu de ce fichier peut être trouvé ici.
Exposition de votre module à TypeScript
Ajouter votre module à la liste des modules située à "lib/browser/api/module-list.ts"
comme suit:
export const browserModuleList: ElectronInternal.ModuleEntry[] = [
{ name: 'apiName', loader: () => require('./api-name') },
];