Electron 개요 및 구조

YiJaeE·2021년 8월 13일
0

Electron

목록 보기
1/3

Electron은 데스크탑 어플리케이션을 만드는 프레임워크다. Electron 공식 문서의 What is Electron? 을 보면 Electron에 대해 다음과 같이 표현한다.

Electron은 JavaScript, HTML 및 CSS를 사용하여 데스크탑 애플리케이션을 구축하기 위한 프레임워크이다. Electron은 Chromium 및 Node.js를 바이너리에 포함함으로써 기본 개발 환경 없이 하나의 JavaScript 코드베이스를 유지하고 Windows, macOS 및 Linux에서 작동하는 크로스-플랫폼 앱을 만들 수 있다.

상술하다시피 Electron을 사용하면 사용자의 플랫폼 환경에 구애받지 않는 데스크탑 어플리케이션을 만들 수 있다. 사용자의 플랫폼 환경에 구애받지 않는다는 것은 크로스브라우징과 같이 플랫폼 또는 브라우저에 대한 최적화 작업이 거의 필요하지 않다는 뜻이다.

이것이 가능한 이유는 Electron이 프론트엔드 영역에서는 Chromium을, 백엔드 영역에서는 Node.js를 사용하기 때문인데, ChromiumNode.js 모두 JavaScript 엔진인 V8을 기반으로 삼고 있다. 따라서 Electron으로 개발할 때는 크롬 브라우저를 기준으로 작업하면 된다.

러프하게 말하면 Electron은 크롬 브라우저를 화면에 띄우는 역할을 한다, 근데 이제 크로스-플랫폼을 곁들인.

또한 Electron 은 JavaScript, HTML, CSS를 활용하는 전통적인 웹개발 방식을 따르기 때문에 React, vue, Angular 와 같은 프레임워크(또는 라이브러리)와 함께 사용할 수 있다.

Electron의 구조

Electron 은 Chromium의 다중 아키텍쳐를 물려받아 Main Process와 Renderer Process라는 두 가지 유형의 프로세스를 제공한다. 어플리케이션의 진입점 역할을 하는 Main Process는 Node.js 환경에서 실행되고, 콘텐츠를 렌더링하는 역할을 하는 Renderer Process는 Chromium 기반으로 동작한다.
Main Process는 하나만 존재하고, Renderer Process는 여러 개가 존재할 수 있다.

실제 Electron의 process 모델은 다음과 같다.

아래는 process 동작을 도식화한 것이다. Electron은 Main Process와 Renderer Process가 통신할 수 있도록 ipcMainipcRenderer모듈을 제공한다.

Main Process

Main Process는 package.json에 기록된 main 스크립트를 호출한다.

// pacakage.json

{
  ...
  "main": "main.js"
  ...
}

Main Process의 주요 목적은 BrowserWindow 모듈을 사용해 새로운 창을 띄우거나 관리하는 것이다.

Main Process는 화면에 창을 띄우고 끄는 기본적인 동작부터 자동 업데이트, 메뉴 커스텀 등의 다양한 기능을 지원한다. 또한 Renderer Process와의 통신을 통해 다양한 화면을 창에 띄우게 된다.

또한 Main Process는 app 모듈을 통해 어플리케이션의 생명주기를 제어한다.

// main.js

const { app, BrowserWindow } = require('electron');

let win;

const createWindow = () => {
  win = new BrowserWindow({
    width: 800,
    height: 600
  })
  
  win.loadURL(url.format({
    pathname: path.join(__dirname, 'index.html'),
    protocol: 'file:',
    slashes: true
  }))
  
  win.on('close', () => {
    win = null
  })
};

app.on('ready', createWindow);

app.on('window-all-closed', () => {
  if (process.platform !== 'darwin') {
    app.quit()
  }
});

app.on('activate', () => {
  if (win === null) {
    createWindow();
  }
});

Renderer Process

Renderer Process는 웹 콘텐츠를 렌더링하는 역할을 하기 때문에 웹 표준에 따라 동작해야 한다. Renderer Process가 Main Process와 같은 권한을 갖게 된다면 사용자의 로컬 환경을 직접 제어하려는 시도가 있을 수도 있으므로 Renderer Process에서 직접 네이티브 API 등을 사용하려면 Main Process와의 통신을 통해야 한다.

ipcMain / ipcRenderer

ipcMain과 ipcRender는 Event Emitter이다. Renderer Process에서 보낸 메세지가 ipcMain을 통해 Main Process로 전송되고 Main Process에서 보낸 메세지가 ipcRenderer를 통해 Renderer Process에 전송된다. 동기/비동기를 모두 지원한다.

  • channel: 메세지를 전송할 때 이벤트 이름
  • event.returnValue: Main Process에서 동기로 메세지에 응답할 경우
  • Event.sender.send(..): Main Process에서 비동기로 메세지에 응답할 경우

다음은 RendererProcess에서 synchronous-message 라는 채널로 Main Process에 'ping'을 보내고 Main Process는 asynchronous-reply라는 채널로 Renderer Process에 'pong'을 전송하는 코드이다.

// main.js

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

ipcMain.on('asynchronous-message', (event, arg) => {
  console.log(arg) // prints "ping"
  event.reply('asynchronous-reply', 'pong')
})

ipcMain.on('synchronous-message', (event, arg) => {
  console.log(arg) // prints "ping"
  event.returnValue = 'pong'
})
// renderer.js

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

console.log(ipcRenderer.sendSync('synchronous-message', 'ping')) // prints "pong"

ipcRenderer.on('asynchronous-reply', (event, arg) => {
  console.log(arg) // prints "pong"
})
ipcRenderer.send('asynchronous-message', 'ping')

마무리

Electron은 개발 과정에서의 편의성을 극대화한 프레임워크다. 각각의 플랫폼마다 약간의 이슈들이 있지만(Linux는 자동 업데이트 지원을 하지 않음) 특정 플랫폼에서 심각한 문제가 있어 별도 처리를 해줘야 하는 일이 상당히 줄어든다. 이것만으로도 Electron을 채택할 충분한 이유가 되는데 Electron은 다양한 API 지원으로 좀 더 풍부한 프로그램 구현이 가능하도록 한다.

게다가 이 모든 것을 JavaScript(Node.js)로 구현할 수 있다!

크로스-플랫폼을 지원하기 때문에 덩치가 다소 크고, Node.js를 포함하고 있기 때문에 보안 측면에서 리스크를 안고 있기는 하지만 다양한 플랫폼을 지원해야 하는 경우 Electron만큼 구현하기 쉬운 프레임워크는 아직까진 없는 것 같다.


참고자료
Electron
Electron 번역 문서
알아두면 유익한 일렉트론 - 자바스크립트로 데스크톱 애플리케이션 개발하기

profile
개발을 개발개발 🐾

0개의 댓글