반응형

React 설치

npx create-react-app .
bashcopy
npm install axios
bashcopy

Electron 설치

npm install --save-dev electron electron-builder
bashcopy

./preload.js 추가

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

contextBridge.exposeInMainWorld('electron', {
    sendMessage: (message) => ipcRenderer.send('send-message', message),
    receiveMessage: (callback) => ipcRenderer.on('receive-message', callback),
    axios: (params) => ipcRenderer.invoke('axios', params),
});
javascriptcopy

./main.js 추가

const {app, BrowserWindow, screen, ipcMain} = require('electron');
const path = require("path");
const axios = require("axios");

let mainWindow;

app.whenReady().then(async () => {
    const {width, height} = screen.getPrimaryDisplay().workAreaSize;

    mainWindow = new BrowserWindow({
        width,
        height,
        webPreferences: {
            preload: path.join(__dirname, 'preload.js'),  // preload.js는 안전하게 IPC를 설정하는 파일
            nodeIntegration: true, // Node.js 사용 가능. ex) fs 모듈
        },
    });

    if (process.env.NODE_ENV === "development") {
        await mainWindow.loadURL("http://localhost:3000");
        mainWindow.webContents.openDevTools();
    } else {
        await mainWindow.loadFile('./build/index.html');
    }
});

ipcMain.on('send-message', (event, arg) => {
    event.reply('receive-message', arg);
});

ipcMain.handle('axios', async (event, params) => {
    const result = await axios(params);
    return result.data;
})
javascriptcopy

./package.json 수정

{
  "name": "electron-react-demo",
  "version": "0.1.0",
  "homepage": ".",
  "private": true,
  "main": "main.js",
  "scripts": {
    "start:react": "NODE_ENV=development BROWSER=none node scripts/start.js",
    "start:electron": "NODE_ENV=development electron .",
    "build:react": "NODE_ENV=production node scripts/build.js",
    "build:electron": "NODE_ENV=production electron-builder"
  },
  "build": {
    "asar": false,
    "files": [
      "build/**/*",
      "preload.js",
      "main.js"
    ]
  }
  // ...
}
jsoncopy

./src/App.js

import {useEffect, useState} from "react";

const App = () => {
  const [input, setInput] = useState('');
  const [message, setMessage] = useState('');

  useEffect(() => {
    window.electron.receiveMessage((event, message) => {
      setMessage(message);
    });
  }, []);

  const handleClickApiCall = async () => {
    const result = await window.electron.axios({
      method: "GET",
      url: "https://jsonplaceholder.typicode.com/todos/1",
    });

    setMessage(JSON.stringify(result));
  };

  return (
      <div>
        <input value={input} onChange={(e) => setInput(e.target.value)}/>
        <button onClick={() => window.electron.sendMessage(input)}>Send Message</button>
        <button onClick={handleClickApiCall}>Api Call</button>
        <div>{message}</div>
      </div>
  );
};

export default App;
javascriptcopy

개발용으로 실행하기

npm run start:react
npm run start:electron
bashcopy

실행파일로 빌드하기

npm run build:react
npm run build:electron
bashcopy
반응형

+ Recent posts