Skip to content

Introduction

@repo/electron-ipc는 Electron 메인 프로세스를 위한 경량 DI/IPC 프레임워크다. NestJS 스타일의 TC39 데코레이터로 서비스와 IPC 핸들러를 선언적으로 구성한다.

왜 필요한가

Electron 메인 프로세스 코드는 규모가 커질수록 관리가 어려워진다:

  • IPC 핸들러가 하나의 파일에 모여 비대해진다
  • 서비스 간 의존성을 수동으로 관리해야 한다
  • 윈도우 생성, 종료 등 lifecycle 처리가 흩어진다
  • 에러 처리가 각 핸들러마다 중복된다

@repo/electron-ipc는 이 문제를 데코레이터 기반 모듈 시스템과 DI 컨테이너로 해결한다.

설계 원칙

앱 무관 (App-agnostic)

프레임워크는 특정 앱에 의존하지 않는다. 로거(logger), 에러 핸들러(onError)를 AppConfig로 외부에서 주입받고, 메인 윈도우 생성은 OnMainWindowCreate를 구현한 provider가 담당한다.

ts
@Injectable()
class WindowService implements OnMainWindowCreate {
  onMainWindowCreate() {
    return new BrowserWindow({ /* 앱이 결정 */ });
  }
}

createApp({
  logger: myLogger,       // 앱이 결정
  onError: handleError,   // 앱이 결정
  modules: [WindowModule, MyModule],
}).start();

Peer Dependency

electron만 peer dependency로 요구한다. 로깅, 윈도우 생성, 에러 처리 등은 소비하는 앱이 결정한다.

TC39 표준 데코레이터

TypeScript 5.0+의 TC39 표준 데코레이터를 사용한다. experimentalDecorators 플래그가 필요 없다.

핵심 구성 요소

구성 요소역할
@Moduleprovider와 controller를 그룹화하는 모듈 단위
@InjectableDI 컨테이너에 등록 가능한 서비스
@Controller(contract)IPC 핸들러 클래스. contract로 클래스 형태를 강제하고, 메서드 이름이 contract 키와 일치하면 자동으로 채널에 바인딩
@UsePipes핸들러에 Pipe를 개별 적용
ControllerOf<C>contract에서 controller가 만족해야 할 클래스 형태를 추출하는 타입
OnMainWindowCreate메인 BrowserWindow를 생성하는 라이프사이클 훅 (구현체 정확히 1개)
EventSourceService가 도메인 이벤트를 발행하는 경량 이벤트 버스
Container싱글톤 레지스트리와 lifecycle 관리
inject()필드 이니셜라이저에서 의존성 주입
createApp()모듈 부트스트랩과 IPC 등록을 수행하는 팩토리
contract()IPC 채널과 타입을 선언적으로 정의. createBridge()createService()가 자동 생성

Lifecycle 순서

resolveAll()            모든 provider를 eagerly resolve

onInit()                윈도우 생성 전 초기화

onMainWindowCreate()    BrowserWindow 생성 (구현 provider가 담당)

onWindowAttach()        윈도우 참조 전달

IPC 핸들러 등록          contract.handles → Guard/Pipe/ExceptionHandler 파이프라인 적용
                        contract.forwards → EventSource 구독 → webContents.send()

onDispose()             윈도우 closed 이벤트 시 정리 (forward 구독 해제 포함)

다음 단계