[Electron] 튜토리얼 Part 2: 첫 데스크탑 앱 만들기

개발 환경 준비

  • 운영체제: Windows 사용 시 WSL(Windows Subsystem for Linux)은 피하는 것이 좋습니다. WSL에서 Electron 실행 시 문제가 발생할 수 있기 때문입니다.
  • 코드 에디터: Visual Studio Code를 추천하며, 확장 기능으로 JavaScript 작업을 최적화할 수 있습니다.
  • 터미널: OS 기본 터미널(Windows: CMD/PowerShell, macOS/Linux: Terminal)을 사용하거나, 에디터 내 터미널을 활용합니다.

npm 프로젝트 초기화

새 프로젝트 폴더를 새성하고 이동

mkdir my-first-electron-app && cd my-first-electron-app

npm으로 프로젝트 초기화

npm init -y

Electron 개발 의존성으로 설치

npm install electron --save-dev

Electron 앱 실행

간단한 메인 스크립트 작성

먼저, 프로젝트 루트에 main.js 파일을 생성하고 아래와 같이 작성합니다. 이 스크립트는 Electron의 메인 프로세스에서 간단한 "Hello" 메시지를 출력하는 예제로, 올바르게 설정되었는지 확인하는 용도입니다.

// main.js
console.log('Hello from Electron');
// package.json에서 start추가 main이 없을 경우 main도 추가
{
  "name": "my-first-electron-app",
  "version": "1.0.0",
  "main": "main.js",
  "scripts": {
    "start": "electron ."
  },
  "devDependencies": {
    "electron": "^23.1.3"
  }
}

터미널에서 npm start를 실행하면 콘솔에 메시지가 출력됩니다.

창 생성과 UI 구현

Electron 애플리케이션은 각 창에 웹 페이지를 로드해 표시합니다.

HTML 파일 생성

프로젝트 루트에 index.html 파일을 생성하고 아래 내용을 추가합니다.

<!DOCTYPE html>
<html lang="ko">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self'">
  <title>Electron 렌더러 예제</title>
</head>
<body>
  <h1>Electron 렌더러에서 인사드립니다!</h1>
  <p>👋 환영합니다.</p>
</body>
</html>

메인 프로세스 코드 업데이트

이제, main.js 파일을 수정하여 위 HTML 파일을 로드하는 BrowserWindow를 생성합니다.

// main.js
const { app, BrowserWindow } = require('electron');
const path = require('path');

// async/await를 활용한 비동기 초기화 함수
async function initializeWindow() {
  try {
    const mainWindow = new BrowserWindow({
      width: 1024,
      height: 768,
      webPreferences: {
        preload: path.join(__dirname, 'preload.js'),
        contextIsolation: true,  // 보안을 위한 옵션
        nodeIntegration: false
      }
    });
    // index.html 파일 로드
    await mainWindow.loadFile('index.html');
  } catch (error) {
    console.error('윈도우 생성 중 오류 발생:', error);
  }
}

// 앱이 준비되면 창 생성
app.whenReady().then(() => {
  initializeWindow();

  // macOS: 앱이 활성화될 때 열린 창이 없으면 새 창 생성
  app.on('activate', () => {
    if (BrowserWindow.getAllWindows().length === 0) {
      initializeWindow();
    }
  });
});

// Windows와 Linux: 모든 창이 닫히면 앱 종료
app.on('window-all-closed', () => {
  if (process.platform !== 'darwin') {
    app.quit();
  }
});

실행

터미널에서 npm start를 실행하고 열리는 창을 확인합니다.