본문 바로가기
프로젝트/ai 미니 프로젝트

[일렉트론][리액트] 프로젝트 구축하기

by 꽁이꽁설꽁돌 2024. 5. 2.
728x90
반응형

목차

     

    일렉트론의 정의

    일렉트론은 javascript만으로도 여러 플랫폼에서 동작할 수 있는 데스크톱 어플리케이션을 만들 수 있게 해 주는

    프레임워크이다.

     

    핵심은 기존에 react로 개발하던 소스 코드를 그대로 사용해도, 일렉트론으로 빌드하여 데스크톱 앱으로 만들어낼 수 있다는 의미이다.

     

    그대로 따라하면 오류가 안날 것이다..

    ㅠㅠㅠㅠㅠ

     

    CRA로 초기 프로젝트 세팅

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

     

    electron 설치

    yarn add electron-is-dev
    yarn add electron electron-builder concurrently cross-env wait-on --dev

     

     

    Node.js 기반 메인 프로세스  파일

    (사실 main.ts파일로 만들고 싶었는데 오류를 해결하지 못해 js로 만들어 주었다는..)

    // main.js
    const { app, BrowserWindow } = await import("electron");
    const path = await import("path");
    const isDev = await import("electron-is-dev");
    
    let mainWindow;
    
    function createWindow() {
     // browser window를 생성합니다.
      mainWindow = new BrowserWindow({
        width: 900,
        height: 680,
        webPreferences: {
          nodeIntegration: true,
          enableRemoteModule: true,
          devTools: isDev,
        },
      });
    
      // 앱의 index.html을 로드합니다.
      mainWindow.loadURL(
        isDev  // 개발 모드인 경우
          ? "http://localhost:3000" // 개발 도구에서 호스팅하는 주소로 로드합니다. 
          : `file://${path.join(__dirname, "../build/index.html")}` // 프로덕션 모드인 경우
      );
    
      if (isDev) mainWindow.webContents.openDevTools({ mode: "detach" });
    
      mainWindow.setResizable(true);
      mainWindow.on("closed", () => {
        mainWindow = null;
        app.quit();
      });
      mainWindow.focus();
    }
    
    app.on("ready", createWindow);
    
     // Linux와 Winodws 앱은 browser window가 열려 있지 않을 때 종료됩니다.
     // macOS는 browser window가 열려 있지 않아도 계속 실행되기 때문에,
     // browser window가 열려 있지 않을 때 앱을 활성화 하면 새로운 browser window를 열어줍니다.
    app.on("activate", () => {
      if (mainWindow === null) createWindow();
    });
     // 개발 도구에서 호스팅하는 주소로 로드합니다. 
    
    // Linux와 Winodws에서는 모든 창을 종료하면 일반적으로 앱이 완전히 종료됩니다.
    app.on("window-all-closed", () => {
      if (process.platform !== "darwin") app.quit();
    });

     

     

    pakage.json

    {
      "main": "./public/main.js",  //main이 있는 상대 경로를 잘 설정해 주어야 함
      "homepage": "./",  //루트 경로를 올바르게 추적 할 수 있도록 함
        "scripts": {
        "start": "react-scripts start",
        "build": "react-scripts build",
        "test": "react-scripts test",
        "eject": "react-scripts eject",
        "electron": "wait-on http://localhost:3000 && electron .", //localhost:3000이 열리고 electron을 실행을 위함
        "compile-main": "tsc ./public/main.js --outdir ./compile-main && tsc ./src/main/preload.js --outdir ./compile-main",
        //./pubilc/main.ts의 컴파일 결과인 main.js를 ./compile-main 디렉토리에 저장합니다.
        "dev": "concurrently \"yarn start\" \"yarn electron\""
        //스크립트를 두 번 작성하는 것은 번거롭기 때문에 하나의 스크립트로 
        //여러 명령어를 동시에 실행하기 위해 concurrently를 이용하여 스트립트를 추가합니다.
      },
    }

     

    preload script

    // preload.ts
    import { contextBridge } from "electron"
    
    contextBridge.exposeInMainWorld('versions', {
        node: () => process.versions.node,
        chrome: () => process.versions.chrome,
        electron: () => process.versions.electron,
    })

    웹 페이지가 로드 되기 전 renderer process에서 실행되는 코드를 작성할 수 있습니다.

    Preload script는 이 index.html이 로드되기 전 시점에 로드할 코드를 작성할 수 있습니다.

     

    폴더 구조

    public말고 src에 만들어 package.json만 잘 수정되면 잘 실행된다.

     

     

    올바르게 로드된 모습

    웹으로 실행되고 일렉트론으로 실행된 모습

     

     

    cannot find module 에러 해결 방법

    진짜 미치는 줄..

    import Canvas from "./Canvas.tsx";
    import MainPage from "./MainPage.tsx";
    function App() {
      return (
        <div>
          <MainPage></MainPage>
        </div>
      );
    }
    
    export default App;

    경로를 ./MainPage에서 끝내지말고 ./MainPage.tsx로 정확히 써주면 된다.

     

     

     

     

    리액트에서 만든 것이 그대로 옮겨지는 것이 정말 신기했고 생산성이 미친 것 같다..

    참고

    https://velog.io/@qhflrnfl4324/Electron-%EC%8B%9C%EC%9E%91%ED%95%98%EA%B8%B0-with-React-TypeScript

     

    Electron 시작하기 with React, TypeScript

    Electron 시작하기 with React, TypeScript

    velog.io

     

    반응형