본문 바로가기
개인프로젝트/listPlz

react-electron 환경설정(윈도우)

by useSword 2024. 1. 23.

관련된 내용들을 검색해보니 맥과 yarn을 이용한 정보가 많았고 electron에 알맞은 환경을 만든 후 react를 설치하는 분들이 많았습니다.

저는 윈도우와 npm을 주로 사용해왔기 때문에 이들로 환경설정을 할 생각입니다.
react를 주로 사용하다보니 우선 react를 설치하고 electron을 추가하여 동시에 작동하는 방식을 사용할 예정입니다.

이렇게 하는 이유는 electron은 변경사항이 있을때마다 새로고침을 해야합니다.이럴바에 react로 빠르게 파악하는 편이 나을  또는 localhost:3000을 지정하여 할 수 있지만 저는 설정하는 방법도 까다로워 보이고 electron을 빠르게 이용하고 싶어 효율적이지 못하게 사용했습니다.


우선 react를 설치하겠습니다.

npx create-react-app listplz

listplz에 자신의 프로젝트 이름이 기입하시면 됩니다.(대문자 안됩니다)

 

설치한 listplz으로 들어가고 

cd listplz

 

그다음 electron을 설치하겠습니다.

npm install --save-dev electron

 

프로젝트 루트(package.json이 있는 공간)에 main.js 파일을 생성합니다.
이 파일은 Electron의 메인 프로세스를 담당합니다.

 

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

// ES6 모듈 import 문법을 사용하여 electron-is-dev를 동적으로 불러옵니다.
let isDev;
(async () => {
  if (process.env.NODE_ENV !== 'production') {
    isDev = (await import('electron-is-dev')).default;
  }
})();

function createWindow() {
  // 브라우저 윈도우를 생성합니다.
  const mainWindow = new BrowserWindow({
    width: 800,
    height: 600,
    webPreferences: {
      contextIsolation: true, // contextIsolation을 true로 설정합니다.
      nodeIntegration: false, // nodeIntegration은 false로 설정합니다.
      preload: path.join(__dirname, 'preload.js') // preload 스크립트 경로를 설정합니다.
    }
  });

  // 개발 중에는 React 개발 서버의 URL을 로드합니다.
  // 프로덕션에서는 빌드된 React 앱을 로드합니다.
  const url = isDev
    ? 'http://localhost:3000'
    : `file://${path.join(__dirname, 'build/index.html')}`;
  mainWindow.loadURL(url);


  // 개발자 도구를 열 수 있습니다.
  if (isDev) {
    mainWindow.webContents.openDevTools();
  }
}

app.whenReady().then(() => {
  createWindow();

  app.on('activate', () => {
    if (BrowserWindow.getAllWindows().length === 0) {
      createWindow();
    }
  });
});

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

 

그리고 같은 위치에 preload.js를 만들면 됩니다.

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

contextBridge.exposeInMainWorld('electronAPI', {
    send: (channel, data) => {
        // whitelist channels
        let validChannels = ["toMain"];
        if (validChannels.includes(channel)) {
            ipcRenderer.send(channel, data);
        }
    },
    receive: (channel, func) => {
        let validChannels = ["fromMain"];
        if (validChannels.includes(channel)) {
            // Deliberately strip event as it includes `sender` 
            ipcRenderer.on(channel, (event, ...args) => func(...args));
        }
    }
});

 

package.json은 아래와 같으면 됩니다.

{
  "name": "listplz2",
  "main": "main.js",
  "homepage": ".",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "@testing-library/jest-dom": "^5.17.0",
    "@testing-library/react": "^13.4.0",
    "@testing-library/user-event": "^13.5.0",
    "react": "^18.2.0",
    "react-dom": "^18.2.0",
    "react-scripts": "5.0.1",
    "web-vitals": "^2.1.4"
  },
  "scripts": {
    "start": "concurrently \"npm run start-react\" \"npm run start-electron\"",
    "build": "react-scripts build",
    "start-react": "react-scripts start",
    "build-react": "react-scripts build",
    "start-electron": "electron ."
  },
  "eslintConfig": {
    "extends": [
      "react-app",
      "react-app/jest"
    ]
  },
  "browserslist": {
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
  },
  "devDependencies": {
    "concurrently": "^8.2.2",
    "electron": "^28.1.4",
    "electron-is-dev": "^3.0.1"
  }
}



완성 시 아래와 같이 보이면 됩니다.

 

 

 

<공부하면서 생긴 오류들>
1. package.json에  "main": "main.js"를 작성하지 않아 아래의 경고문이 나타나며 되지 않았음



2. electron-is-dev 모듈이 ES 모듈 형식으로 되어 있으며, 이를 CommonJS 형식의 require() 문법으로 불러오려고 할 때 발생한 오류가 있었습니다.  require() 대신에 import() 문법을 사용하여 해결했습니다.
또는 다운그레이드도 좋은 방법이었겠지만 다른 라이브러리와 호환문제가 생길 것 같아 다운그레이드는 진행하지 않았습니다.

3. Not allowed to load local resource: file:///E:/build/index.html라는 에러가 나타났었습니다.
이 부분은 package.json에서 "homepage": ".",를 작성하고 main.js에서 아래와 같은 코드를 작성함으로써 해결했습니다.

const url = isDev
  ? 'http://localhost:3000'
  : `file://${path.join(__dirname, 'build/index.html')}`;
mainWindow.loadURL(url);



'개인프로젝트 > listPlz' 카테고리의 다른 글

listplz - DB에 변수 추가하기, taskProgressBar  (0) 2024.02.06
listplz 데이터 상호작용  (1) 2024.02.02
indexedDB  (0) 2024.01.31