[Electron] 프로세스 모델: 메인과 렌더러의 조화로운 협력

Electron의 프로세스 구조

Electron은 Chromium과 Node.js를 결합한 프레임워크로, 각 앱은 다음과 같은 두 가지 프로세스로 나뉘어 동작합니다.

  • 메인 프로세스:  애플리케이션의 중심 역할을 하며, 단일 인스턴스로 실행됩니다.
  • 렌더러 프로세스: 각 창(window)마다 별도로 생성되며, UI를 렌더링합니다.

메인 프로세스의 역할

메인 프로세스는 애플리케이션의 진입점으로, Node.js 환경에서 실행됩니다. 이 프로세스는 애플리케이션의 창을 생성하고 관리하는 역할을 하며, 운영 체제와 상호작용할 수 있습니다.

  • 앱 생명주기 관리: app 모듈을 통해 앱의 시작, 종료, 활성화 등을 제어합니다.
  • 창 생성 및 관리: BrowserWindow를 사용해 UI 창을 생성하고 조작합니다.
  • Node.js 환경: 파일 시스템, 네트워크, OS 기능 등에 접근할 수 있는 완전한 Node.js 런타임을 제공합니다.
  • IPC 중개: 렌더러 프로세스와의 통신을 조율합니다.

메인 프로세스는 단일 스레드로 실행되며, 앱 전체를 관장하는 컨트롤 타워 역할을 합니다.

렌더러 프로세스의 역할

BrowserWindow 인스턴스는 렌더러 프로세스를 통해 웹 콘텐츠를 렌더링합니다. 렌더러 프로세스는 Chromium을 기반으로 동작하며, 일반적인 웹 기술(HTML, CSS, JavaScript)을 사용해 UI를 구축할 수 있습니다.

  • UI 렌더링: HTML, CSS, JavaScript를 실행해 사용자 인터페이스를 표시합니다.
  • 웹 환경: Chromium의 웹뷰와 유사하며, DOM 조작과 이벤트 처리를 담당합니다.
  • 제한된 권한: 기본적으로 Node.js나 OS 기능에 직접 접근할 수 없어 보안이 강화됩니다.

렌더러는 여러 개가 동시에 실행될 수 있으며, 각 창이 독립적으로 동작합니다.

프리로드 스크립트

렌더러 프로세스는 기본적으로 Node.js API에 접근할 수 없습니다. 그러나 프리로드 스크립트를 사용하면 제한된 환경 내에서 Node.js 기능을 사용할 수 있습니다. Electron은 ipcMain과 ipcRenderer 모듈을 제공하며, Preload 스크립트를 통해 안전한 통신을 보장합니다.

유틸리티 프로세스

Electron 25부터는 유틸리티 프로세스(Utility Process) 를 사용할 수 있습니다. 이 프로세스는 CPU 집중적인 작업이나 신뢰할 수 없는 서비스를 실행하는 데 적합합니다.

const { UtilityProcess } = require('electron');

const worker = new UtilityProcess({
  path: 'path/to/worker.js'
});

worker.on('message', (data) => {
  console.log('Received:', data);
});

유틸리티 프로세스는 렌더러 프로세스와 MessagePorts를 통해 직접 통신할 수 있다는 점에서 기존의 child_process.fork()와 차별화됩니다.