Appearance
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 플래그가 필요 없다.
핵심 구성 요소
| 구성 요소 | 역할 |
|---|---|
@Module | provider와 controller를 그룹화하는 모듈 단위 |
@Injectable | DI 컨테이너에 등록 가능한 서비스 |
@Controller(contract) | IPC 핸들러 클래스. contract로 클래스 형태를 강제하고, 메서드 이름이 contract 키와 일치하면 자동으로 채널에 바인딩 |
@UsePipes | 핸들러에 Pipe를 개별 적용 |
ControllerOf<C> | contract에서 controller가 만족해야 할 클래스 형태를 추출하는 타입 |
OnMainWindowCreate | 메인 BrowserWindow를 생성하는 라이프사이클 훅 (구현체 정확히 1개) |
EventSource | Service가 도메인 이벤트를 발행하는 경량 이벤트 버스 |
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 구독 해제 포함)다음 단계
- First Steps — 설치와 최소 부트스트랩 예제
- Modules — 모듈 단위로 기능을 구성하는 방법
- API Reference — 전체 API 시그니처