ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Electron with React (+TypeScript)
    Archive/메모노트 데스크탑 앱 2022. 6. 29. 20:02

    기본 설정

    Electron에서 화면을 render 하는 방법으로는 html 파일을 사용하거나, 특정 웹페이지의 URL을 사용하는 방법이 있다.

    이때 React는 Build를 통해 완성된 html, css, js파일을 생성해낼 수 있기 때문에 이렇게 Build 된 파일을 Electron이 읽도록 하기만 하면 된다.

     

    하지만 문제는 개발환경에서 React를 사용할 때 발생한다. React를 통해 개발을 할 때는 보통 일일이 Build를 진행하지 않고, DevServer를 이용하여 변경점을 즉각적으로 반영해가며 개발을 진행한다.

     

    따라서 이렇게 개발환경에서는 Build에 의해 만들어진 static 한 파일이 존재하지 않기 때문에, Electron에서는 URL방식을 이용하여 개발서버의 주소를 연결하는 방식을 사용해야 한다.

    React with TypeScript

    프로젝트를 먼저 생성하기 위해 평소 React 프로젝트를 생성하듯이 create-react-app을 이용한다.

    단, 이번 프로젝트에서는 TypeScript를 이용할 생각이다. 따라서 --template typescript 옵션을 추가로 이용한다.

    npx create-react-app electron-with-react --template typescript

    여기서 electron-with-react는 이번 프로젝트에서 사용할 프로젝트명이다. 원하는 대로 아무렇게나 설정 가능하다.

    중요한 것은 --template typescript 옵션을 추가로 사용해주는 것이다. 이를 통해 React 프로젝트를 매우 간단하게 TypeScript 방식으로 시작할 수 있다.

     

    이후 package.json에서 아래와 같이 homepage 설정을 해준다.

    {
      ...
      "homepage": "./"
    }

    Electron

    다음으로는 Electron을 세팅한다.

     

    이를 위해 npm을 이용해 electron을 설치한다. 이때 electron은 devDependencies로 설치한다.

    npm i electron -D

    설치가 모두 끝났다면, public 디렉터리에 main.js라는 파일을 생성한다.

    해당 파일이 Electron의 시작점이 될 것이다.

     

    이때 이 파일을 Electron의 시작점으로 사용할 것이라는 것을 알리기 위해 package.json에 main을 설정한다.

    {
      ...
      "main": "public/main.js",
      "homepage": "./"
    }

    Electron Entry file 작성

    위의 기본 설정에서 public 디렉터리의 main.js 파일을 Electron의 시작이 되는 파일로 설정하였다.

    따라서 이번에는 이 main.js 파일을 이용해 Electron이 제대로 동작할 수 있도록 기본적인 부분을 작성한다.

    const { app, BrowserWindow } = require("electron");
    const path = require("path");
    
    const createWindow = () => {
      const win = new BrowserWindow({
        width: 1200,
        height: 700,
      });
      win.loadURL("http://localhost:3000");
    };
    
    app.whenReady().then(createWindow)
    
    app.on("window-all-closed", () => {
      if (process.platform !== "darwin") app.quit();
    });
    
    app.on("activate", function () {
      if (BrowserWindow.getAllWindows().length === 0) createWindow();
    });

    Electron은 처음 사용해보기 때문에 각각이 정확히 어떤 의미를 가지고 있는지는 확실하게 알지 못한다.

    위의 코드는 Electron 공식 홈페이지에서 제공하는 Quick Start 문서를 참고하여 작성하였다.

     

    Quick Start | Electron

    This guide will step you through the process of creating a barebones Hello World app in Electron, similar to electron/electron-quick-start.

    www.electronjs.org


    실행하기

    concurrently

    React를 실행하기 위해서는 "npm start"라는 스크립트를 사용하고, Electron을 실행하기 위해서는 "electron ."라는 스크립트를 사용한다.

     

    이때 한 번에 여러 명령을 동시에 실행하기 위해서는 concurrently라는 도구를 사용할 수 있다.

    npm i concurrently -D

    이를 이용해 package.json에 스크립트를 작성하면 다음과 같다.

    "scripts": {
      "start": "concurrently \"npm run reactStart\" \"npm run electronStart\"",
      "build": "react-scripts build",
      "test": "react-scripts test",
      "eject": "react-scripts eject",
      "reactStart": "react-scripts start",
      "electronStart": "electron ."
    },

    concurrently를 이용하여 React를 실행시키는 reactStart 스크립트와, Electron을 실행시키는 electronStart 스크립트를 동시에 실행시킬 수 있게 되었다.

     

    따라서 "npm start"라는 비교적 간단한 방식으로 프로젝트 개발환경을 실행시킬 수 있다.

    wait-on

    하지만 여전히 문제가 남아있다. Electron에서 화면을 요청하는 순간에 React의 DevServer가 미처 준비되지 못한다면, Electron의 화면에는 아무것도 보이지 않게 된다.

     

    따라서 이를 위해 wait-on을 사용한다. wait-on을 이용하면 특정 파일이나 소켓, http 리소스와 같은 자원이 준비되는 시간 동안 기다린 후 다음 작업을 진행하는 것이 가능하다.

    "scripts": {
      "start": "concurrently \"npm run reactStart\" \"npm run electronStart\"",
      "build": "react-scripts build",
      "test": "react-scripts test",
      "eject": "react-scripts eject",
      "reactStart": "react-scripts start",
      "electronStart": "wait-on http://localhost:3000 && electron ."
    },

    React의 브라우저 화면 생성 문제

    이제 문제없이 하나의 스크립트를 가지고 개발을 시작할 수 있다. 하지만 해당 스크립트를 실행할 때마다 React의 스크립트에 의해 브라우저 창이 새로 뜬다는 것은 굉장히 거슬리는 일이다.

     

    기존의 React 개발에서는 브라우저를 이용해 개발을 진행하였기에 자동으로 창을 열어주는 것이 편리했지만, 지금은 Electron을 이용해 개발을 진행할 것이기 때문에 브라우저가 필요 없다.

     

    따라서 React의 환경변수 파일에 BROWSER=none 설정을 해서 이를 막을 수 있다.

    BROWSER=none

    React의 환경변수 파일은 .env이다. 이는 프로젝트의 root 디렉터리에 직접 생성하여 사용하면 된다.


    참고

    https://blog.codefactory.ai/electron/create-desktop-app-with-react-and-electron/1-project-setting/

    https://pks2974.medium.com/electron-%EC%97%90-react-%EC%A0%81%EC%9A%A9%ED%95%B4-%EB%B3%B4%EA%B8%B0-ebcea2bbbd27

    https://developer-talk.tistory.com/335

    댓글