새로운 Electron 브라우저 모듈 만들기
Electron API 가이드에 오신 것을 환영합니다! browser
디렉토리 내에 새로운 Electron API 모듈을 만드는 방법에 익숙하지 않다면, 이 가이드는 구현해야 할 몇 가지 필수 단계를 체크리스트 형태로 제공합니다.
이 가이드는 Electron 브라우저 API를 만드는 데 필요한 모든 것을 다루는 종합적인 설명서가 아니라, 직관적이지 않은 몇 가지 단계를 기록한 개요입니다.
Electron 프로젝트 설정에 파일 추가하기
Electron은 GN을 메타 빌드 시스템으로 사용하여 컴파일러인 Ninja를 위한 파일을 생성한다. 따라서 여러분의 코드를 컴파일하도록 Electron에 알리려면, API 코드와 헤더 파일 이름을 filenames.gni
파일에 추가해야 한다.
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
은 C++ 객체가 v8 래퍼 객체를 가질 때 사용하는 기본 클래스다.
API에 object_template_builder
와 wrappable
을 통합하기 위해 추가해야 하는 기본적인 코드 예제는 다음과 같다. 더 많은 구현 예제는 여기에서 확인할 수 있다.
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
파일에는 다음과 같은 코드를 작성한다:
#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
Electron API와 Node 연결하기
typings/internal-ambient.d.ts
파일에서 Process
인터페이스에 새로운 속성을 추가해야 한다. 코드는 다음과 같다:
interface Process {
_linkedBinding(name: 'electron_browser_{api_name}'): Electron.ApiName;
}
api_name.cc
파일의 가장 하단에 다음 코드를 추가한다:
NODE_LINKED_BINDING_CONTEXT_AWARE(electron_browser_{api_name},Initialize)
shell/common/node_bindings.cc
파일에서 Node 바인딩 이름을 Electron의 내장 모듈에 추가한다.
#define ELECTRON_BROWSER_MODULES(V) \
V(electron_browser_{api_name})
참고: Node와 Electron을 연결하는 방법에 대한 더 자세한 기술적 내용은 블로그 글에서 확인할 수 있다.
TypeScript로 API 노출하기
API를 모듈로 내보내기
다음 경로에 새로운 TypeScript 파일을 생성해야 한다:
"lib/browser/api/{electron_browser_{api_name}}.ts"
이 파일의 내용 예제는 여기에서 확인할 수 있다.
모듈을 TypeScript에 노출하기
"lib/browser/api/module-list.ts"
파일의 모듈 목록에 다음과 같이 모듈을 추가한다:
export const browserModuleList: ElectronInternal.ModuleEntry[] = [
{ name: 'apiName', loader: () => require('./api-name') },
];