Electron 공식문서를 번역한 내용입니다.
Electron은 현대 웹브라우저와 매우 유사하게 만드는 Chrominum의 멀티 프로세스 아키텍처를 계승했다. 이 가이드에서는 minimal quick start app에서 적용한 Electron의 개념적 지식을 자세히 설명합니다.
Why not a single process?
웹 브라우저는 엄청나게 복잡한 애플리케이션이다. 웹 콘텐츠를 표시하는 기본 기능 외에도 여러 창(또는 탭) 관리 및 third-party extensions 로딩과 같은 많은 보조 책임이 있습니다.
초창기 브라우저들은 보통 이 모든 기능들을 위해 하나의 프로세스를 사용하였다. 이 패턴은 열려 있는 각 탭에 대한 오버헤드가 적다는 것을 의미하지만 웹 사이트 하나가 손상되거나 중단되면 전체 브라우저에 영향을 미칩니다.
The multi-process model
이 문제를 해결하기 위해 크롬 팀은 각 탭이 자체 프로세스로 렌더링되도록 결정하여 웹 페이지의 버그나 악성 코드가 앱 전체에 끼칠 수 있는 피해를 제한하였다. 그런 다음 단일 브라우저 프로세스가 이러한 프로세스뿐만 아니라 애플리케이션 수명 주기 전체를 제어합니다. 아래의 Chrome Comic 그림은 이 모델을 보여줍니다.
Electron은 매우 유사하게 구조화된다. 앱 개발자는 기본 프로세스와 렌더러라는 두 가지 유형의 프로세스를 제어합니다. 이것들은 위에서 설명한 크롬의 자체 브라우저 및 렌더러 프로세스와 유사하다.
The main process
각 Electron앱은 애플리케이션의 진입점 역할을 하는 하나의 주요 프로세스를 가지고 있다. 주 프로세스는 Node.js 환경에서 실행되며 이는 모듈들을 require하고 모든 Node.js API를 사용할 수 있다는 것을 의미한다.
Window management
main프로세스의 주된 목적은 BrowserWindow모듈을 사용하여 응용 프로그램 창을 만들고 관리하는 것입니다.
BrowserWindow 클래스의 각 인스턴스는 별도의 렌더러 프로세스에서 웹 페이지를 로드하는 응용 프로그램 창을 만듭니다. window의 webContents 객체를 사용하여 기본 프로세스에서 이 웹 컨텐츠와 상호 작용할 수 있습니다.
main.js
const { BrowserWindow } = require('electron')
const win = new BrowserWindow({ width: 800, height: 1500 })
win.loadURL('https://github.com')
const contents = win.webContents
console.log(contents)
참고: BrowserView 모듈과 같은 web embeds에 대해서도 렌더러 프로세스가 만들어집니다. webContents 오브젝트는 내장된 웹 컨텐츠에도 액세스할 수 있습니다.
BrowserWindow 모듈이 EventEmitter이기 때문에 다양한 사용자 이벤트(예: 창 최소화 또는 최대화)에 대한 핸들러를 추가할 수도 있습니다.
BrowserWindow 인스턴스가 삭제되면 해당 렌더러 프로세스도 종료됩니다.
Application lifecycle
또한 main프로세스는 Electron의 app 모듈을 통해 응용 프로그램의 수명 주기를 제어합니다. 이 모듈에서는 사용자 정의 응용 프로그램 동작(예: 응용 프로그램 종료, 응용 프로그램 독 수정 또는 정보 패널 표시)을 추가하는 데 사용할 수 있는 다양한 이벤트 및 메서드 집합을 제공합니다.
실제적인 예로, quick start guide에 나와 있는 앱은 app API를 사용하여 보다 네이티브한 애플리케이션 창 환경을 만듭니다.
main.js
// quitting the app when no windows are open on non-macOS platforms
app.on('window-all-closed', function () {
if (process.platform !== 'darwin') app.quit()
})
Native APIs
Electron의 기능을 웹 콘텐츠용 Chromium wrapper 이상으로 확장하기 위해 main 프로세스는 사용자 정의 API를 추가하여 사용자의 운영 체제와 상호 작용한다. Electron은 메뉴, dialogs 및 tray icons과 같은 기본 데스크톱 기능을 제어하는 다양한 모듈을 노출합니다.
Electron의 주요 프로세스 모듈의 전체 목록은 API 설명서를 참조하십시오.
The renderer process
각 Electron 앱은 열려 있는 브라우저 BrowserWindow(및 각 web embed)에 대해 별도의 렌더러 프로세스를 생성한다. 이름에서 알 수 있듯이 렌더러는 웹 콘텐츠를 렌더링합니다. 모든 면에서 렌더러 프로세스에서 실행되는 코드는 (최소한 크롬이 하는 한) 웹 표준에 따라 동작해야 한다.
따라서 단일 브라우저 창 내의 모든 사용자 인터페이스 및 앱 기능은 웹에서 사용하는 것과 동일한 도구와 패러다임을 사용하여 작성되어야 합니다.
모든 웹 사양에 대한 설명은 본 가이드의 범위를 벗어났지만, 최소한으로 이해해야 할 사항은 다음과 같습니다.
- HTML 파일은 렌더러 프로세스의 진입점입니다.
- UI 스타일은 CSS(Cascading Style Sheet)를 통해 추가됩니다.
- 실행 가능한 자바스크립트 코드는 <script>요소를 통해 추가할 수 있습니다.
게다가, 이것은 렌더러가 require나 다른 Node.js API에 직접 접근할 수 없음을 의미한다. 렌더러에 NPM 모듈을 직접 포함하려면 웹에서 사용하는 것과 동일한 번들러 toolchains(예: webpack 또는 parcel)을 사용해야 합니다.
참고: 렌더러 프로세스는 개발을 쉽게 하기 위해 전체 Node.js 환경에서 생성될 수 있습니다. 이전에는 이 기능이 기본값이었으나 보안상의 이유로 비활성화되었습니다.
이 때 렌더러 프로세스 사용자 인터페이스가 main프로세스에서만 액세스할 수 있는 경우 Node.js 및 Electron의 기본 데스크톱 기능과 어떻게 상호 작용할 수 있는지 궁금할 수 있습니다. 사실 Electron의 콘텐츠 스크립트를 직접 가져올 방법은 없다.
Preload scripts
Preload스크립트에는 웹 콘텐츠가 로드되기 전에 렌더러 프로세스에서 실행되는 코드가 포함되어 있습니다. 이러한 스크립트는 렌더러 컨텍스트 내에서 실행되지만 Node.js API에 액세스하여 더 많은 권한을 부여합니다.
Preload 스크립트는 BrowserWindow생성자의 webPreferences옵션으로 main프로세스에 첨부할 수 있습니다.
main.js
const { BrowserWindow } = require('electron')
//...
const win = new BrowserWindow({
webPreferences: {
preload: 'path/to/preload.js'
}
})
//...
Preload스크립트는 렌더러와 global Window interface를 공유하고 Node.js API에 액세스할 수 있으므로, 웹 컨텐츠가 사용할 수 있는 임의의 API를 전역 window에 노출하여 렌더러를 향상시킵니다.
Preload스크립트가 연결된 렌더러와 전역 window을 공유하지만 contextIsolation기본값 때문에 프리로드 스크립트에서 window로 직접 변수를 연결할 수 없습니다.
preload.js
window.myAPI = {
desktop: true
}
renderer.js
console.log(window.myAPI)
// => undefined
Context Isolation은 preload스크립트를 renderer의 main world와 분리하여 권한 있는 API가 웹 콘텐츠의 코드로 유출되는 것을 방지하는것을 의미합니다.
대신 contextBridge모듈을 사용하여 이 작업을 안전하게 수행하십시오.
preload.js
const { contextBridge } = require('electron')
contextBridge.exposeInMainWorld('myAPI', {
desktop: true
})
renderer.js
console.log(window.myAPI)
// => { desktop: true }
이 기능은 두 가지 주요 목적에 매우 유용합니다.
- ipcRenderer helpers를 렌더러에 노출시키면 프로세스 간 통신(IPC)을 사용하여 렌더러에서 기본 프로세스 태스크를 트리거할 수 있습니다(그 반대도 가능).
- 원격 URL에 호스팅되는 기존 웹 앱의 Electron wrapper를 개발하는 경우 웹 클라이언트 측의 데스크톱 전용 logic에 사용할 수 있는 사용자 지정 속성을 렌더러 window 글로벌에 추가할 수 있습니다.
'Electron' 카테고리의 다른 글
Electron 시작하기 (2) (0) | 2021.10.27 |
---|---|
Electron 시작하기 (1) (0) | 2021.10.26 |