๐ Electron + React ํ๋ก์ ํธ ๊ตฌ์ถํ๊ธฐ
(24-04-01 ์ถ๊ฐ) electron-is-dev ๋ชจ๋์ด ESM ๋ฐฉ์์ ์ง์ํ๊ธฐ ์์ํด์
CJS, require์์ MJS, import ๋ฐฉ์์ ์ฌ์ฉํ๋๋ก ๊ธ ๋ด์ฉ์ ๋ณ๊ฒฝํ์ต๋๋ค.
๐ Electron์ด๋
Chromium๊ณผ Node.js๋ฅผ ํ๋์ ๋ฐํ์์ผ๋ก ํตํฉํ์ฌ
JS, HTML, CSS ๊ฐ์ ๊ธฐ๋ณธ์ ์ธ ์น ์ง์์ผ๋ก๋ ๋ฐ์คํฌํฑ ์ ํ๋ฆฌ์ผ์ด์ ์ ๋ง๋ค ์ ์๋ ํ๋ ์์ํฌ ์ ๋๋ค.
์ด๊ฑธ๋ก ๋ฐ์คํฌํฑ ์ ํ๋ฆฌ์ผ์ด์ ์ ์ด๋ป๊ฒ ๋ง๋๋ ์ถ๊ฒ ์ง๋ง ์ด๋ฏธ ์ฐ๋ฆฌ๊ฐ ์ฌ์ฉํ๊ณ ์๋
VSCode, Slack, Skype, Figma ๋ฑ๋ฑ๋ฑ ์ด๋ฏธ ๊ฒ์ฆ๋ ์๋น์ค๋ค์์ ์ฌ์ฉํ๊ณ ์์ต๋๋ค.
๋ํ ๋น๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ํตํด ํ๋์ ์๋ฐ์คํฌ๋ฆฝํธ ์ฝ๋๋ฅผ ์๋์ฐ, ๋งฅ, ๋ฆฌ๋ ์ค์์
ํํ ๋ณด๋ ์ค์น ํ๋ก๊ทธ๋จ์ ํํ๋ก ํจํค์งํ ์ ์์ด ๋ฏธ์น ์์ฐ์ฑ์ ๋ณด์ฌ์ค๋๋ค.
๊ทธ๋ผ ํ๋ก์ ํธ๋ฅผ ์์ฑํด๋ณด๊ฒ ์ต๋๋ค.
- ์ด ๊ธ์์๋ ๋ฆฌ์กํธ ๋ค์ดํฐ๋ธ์ ์น์ฑ๊ณผ ๊ฐ์ด React ์น ํ๋ก์ ํธ๋ฅผ Electron์ผ๋ก ๊ฐ์ผ ํํ์ ํ๋ก๊ทธ๋จ์ ์ ์ํฉ๋๋ค.
- ๊ทธ๋ ๊ธฐ์ Electron ๊ด๋ จ ์ค์ ์ ๊ฑฐ์ ๊ฑด๋๋ฆด ํ์๊ฐ ์์ด ๋ฌ๋์ปค๋ธ๊ฐ ๊ฑฐ์ ์๋ค๊ณ ๋ณผ ์ ์์ต๋๋ค.
- ์ต์ข ํจํค์ง ํ์ผ์๋ ๋ฆฌ์กํธ ํ๋ก์ ํธ๋ฅผ ๋ฒ๋ค๋งํ ์ฐ์ถ๋ฌผ ๊น์ง ํฌํจ๋์ด ์์ด ๋ณ๋์ ์น์๋ฒ๊ฐ ํ์ํ์ง ์์ต๋๋ค.
๐ Node.js ๋ฐ yarn ์ค์นํ๊ธฐ
Node.js๊ฐ ์ค์น ๋์ง ์์๋ค๋ฉด nvm ๋ฐ ๊ณต์ ํํ์ด์ง์์ ์ค์นํด์ฃผ์ธ์.
$ npm i -g yarn
$ yarn -v // ๋ฒ์ ์ด ํ์๋๋ค๋ฉด ์ ์ ์ค์น
์ ํฌ๊ฐ ํจํค์งํ ๋ ์ฌ์ฉํ electron-builder
๋ผ์ด๋ธ๋ฌ๋ฆฌ๊ฐ yarn
์ฌ์ฉ์ ๊ฐ๋ ฅ ๊ถ์ฅํ๊ธฐ ๋๋ฌธ์ ๊ธ๋ก๋ฒ๋ก ์ค์นํด์ค๋๋ค.
๐ CRA๋ก ์ด๊ธฐ ํ๋ก์ ํธ ์ธํ
$ npx create-react-app electron-app --template typescript
CRA๋ฅผ ์ด์ฉํด ๋ฆฌ์กํธ ํ๋ก์ ํธ๋ฅผ ์์ฑํด์ค๋๋ค.
์ ๋ TS๋ฅผ ์ฌ์ฉํ๊ธฐ ๋๋ฌธ์ ํ ํ๋ฆฟ์ ์ ์ฉํด ํ๋ก์ ํธ๋ฅผ ์์ฑํ์ต๋๋ค.
๐ Electron ํจํค์ง ์ค์น
$ npm i electron-is-dev
$ npm i -D electron electron-builder concurrently cross-env wait-on
์์์ ์ค์นํ ํจํค์ง๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
electron-is-dev
๊ฐ๋ฐ ํ๊ฒฝ๊ณผ ํ๋ก๋์ ํ๊ฒฝ์ ํ์ธelectron
์ผ๋ ํธ๋ก ํจํค์ง์ ๋๋ค.electron-builder
์ผ๋ ํธ๋ก ์ ํจํค์งํ๋ ๋ชจ๋์ ๋๋ค.
์ ๋ง ๋ค์ํ ์ต์ ์ด ์์ผ๋ ๊ณต์๋ฌธ์๋ฅผ ๊ผญ ์ฐพ์๋ณด๊ธธ ๋ฐ๋๋๋ค.concurrently
๋ ๊ฐ ์ด์์ ๋ช ๋ น์ด๋ฅผ ํ๋์ ์คํฌ๋ฆฝํธ์์ ์คํํ ์ ์๋๋ก ํด์ค๋๋ค.cross-env
์ด์์ฒด์ ๋ง๋ค ๋ค๋ฅธ ํ๊ฒฝ๋ณ์ ์ค์ ์ ํต์ผ์์ผ์ค๋๋ค.wait-on
Node ํ๊ฒฝ์์ ํ๋ ์ด์์ ํฌํธ, ์์ผ๊ฐ์ ์์์ด ์ฌ์ฉ ๊ฐ๋ฅํด์ง ๋๊น์ง ๋๊ธฐํ๋๋ก ์ง์ฐ์ํค๋ ๋ชจ๋์ ๋๋ค.
๐ Main Process ํ์ผ ์์ฑ
Electron์์ ๋ฉ์ธ ํ๋ก์ธ์ค ํ์ผ์ ์ ํ๋ฆฌ์ผ์ด์ ์ ์ง์ ์ ์ด๋ฉฐ,
Electron API๋ฅผ ์ฌ์ฉํ์ฌ ์ ํ๋ฆฌ์ผ์ด์ ์ ๋ผ์ดํ์ฌ์ดํด์ ๊ด๋ฆฌํฉ๋๋ค.
Node.js ๊ธฐ๋ฐ์์ ๋์๊ฐ๋ ๋ฉ์ธ ํ๋ก์ธ์ค ํ์ผ์ ์์ฑํด ์ฃผ๋๋ก ํ๊ฒ ์ต๋๋ค.
// public/electron.js
const { app, BrowserWindow } = await import("electron");
const path = await import("path");
const isDev = await import("electron-is-dev");
let mainWindow;
function createWindow() {
mainWindow = new BrowserWindow({
width: 900,
height: 680,
webPreferences: {
nodeIntegration: true,
enableRemoteModule: true,
devTools: isDev,
},
});
// ***์ค์***
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);
app.on("activate", () => {
if (mainWindow === null) createWindow();
});
app.on("window-all-closed", () => {
if (process.platform !== "darwin") app.quit();
});
- ๊ฒฝ๋ก: public ์๋์ ๋์ด์ผ ๋น๋ ํ build ํด๋ ๋ฐ๋ก ์๋์ electron.js ํ์ผ์ด ์์ฑ๋์ด ์ง์ ์ ์ญํ ์ ํ๊ธฐ ์์ํด์ง๋๋ค.
- ํ์ผ๋ช
: electron-builder๊ฐ ์ธ์ํ๋ default ๋ฉ์ธ ํ๋ก์ธ์ค ํ์ผ ์ด๋ฆ์ด
electron.js
์ ๋๋ค.
๋ณ๋ ์ค์ ํ๊ณ ์ถ์ง ์์ผ๋ฉด ํ์ผ ์์น์ ์ด๋ฆ ๊ทธ๋๋ก ๊ฐ๋๊ฒ ์ข์ต๋๋ค.
์ฝ๋ ๋ด ์ค์ํ์ํ ๋ถ๋ถ์ ๊ฐ๋ฐ ํ๊ฒฝ์ผ ๊ฒฝ์ฐ์๋ ๊ฐ๋ฐ ์๋ฒ๋ฅผ ์คํ์ํค๊ณ ,
ํ๋ก๋์ ํ๊ฒฝ์ผ ๊ฒฝ์ฐ์๋ ๋น๋ ํ์ผ์ ์ฐพ์ ์คํ์ํจ๋ค๋ ์๋ฏธ์ ๋๋ค.
์ด๋ฌํ ์ด์ ๋๋ฌธ์ ํจํค์งํ ํ์ผ์ ๋ณ๋์ ์น ์๋ฒ ์์ด ์์ฒด์ ์ผ๋ก ๊ตฌ๋์ด ๊ฐ๋ฅํฉ๋๋ค.
๐ package.json ์ค์
"type": "module",
"main": "public/electron.js",
"homepage": ".",
"scripts": {
"react-start": "react-scripts start",
"react-build": "react-scripts build",
"start": "concurrently \"cross-env NODE_ENV=development BROWSER=none yarn react-start\" \"wait-on http://localhost:3000 && electron .\"",
"build": "yarn react-build && electron-builder",
"build:win": "yarn react-build && electron-builder --win --x64"
},
type
ํ๋ก์ ํธ๋ฅผ mjs ๋ฐฉ์์ผ๋ก ์ฌ์ฉํฉ๋๋ค.main
์ผ๋ ํธ๋ก ์ ์ํธ๋ฆฌ ํ์ผ ๊ฒฝ๋ก์ ๋๋ค.start
๊ฐ๋ฐ์๋ฒ๊ฐ ์คํ๋๊ธฐ ๊น์ง ๊ธฐ๋ค๋ฆฐ ํ ์ผ๋ ํธ๋ก ์ ์คํํฉ๋๋ค.build
๋จผ์ ๋ฆฌ์กํธ ํ๋ก์ ํธ๋ฅผ ๋น๋ํด ๋ฒ๋คํ์ผ์ ์์ฑํ ํ ๊ทธ ๋ฒ๋คํ์ผ์ ํฌํจํ์ฌ ์ผ๋ ํธ๋ก ์ผ๋ก ํจํค์งํฉ๋๋ค.
์ต์ ์์ด electron-builder๊ฐ ์คํ๋ ๊ฒฝ์ฐ ํ์ฌ ๊ตฌ๋ํ๋ ํ๊ฒฝ์ ๋ง์ถฐ์ ํจํค์งํฉ๋๋ค.
์ ์๋์ฐ ํจํค์ง๊ณผ ๊ฐ์ด ๋ง์ ํ๊ฒฝ์ ๋ง์ถ ์ต์ ๋ค์ด ๋ง๊ธฐ ๋๋ฌธ์ electron-builder ๊ณต์๋ฌธ์๋ฅผ ์ฐธ๊ณ ํด ์คํฌ๋ฆฝํธ๋ฅผ ์์ฑํด์ค๋๋ค.
์คํฌ๋ฆฝํธ ์์ฑ์ด ๋๋ ํ $ npm start
๋ก ๊ฐ๋ฐ ํ๊ฒฝ์ ์คํํ๋ฉด ๋ค์๊ณผ ๊ฐ์ด ์คํ๋ฉ๋๋ค.
์คํ ์ดํ ํ์ ๋ฆฌ์กํธ๋ฅผ ๋ค๋ฃจ๋ ๊ฒ์ฒ๋ผ ๊ฐ๋ฐํ๋ฉด ๋ฉ๋๋ค.
ํ์ฌ์์ ๋ฐ์คํฌํฑ ์ฑ์ ๋ง๋ค ์ผ์ด ์์ด ์ฌ๋ด์์ ์ฒ์ ์ฌ์ฉํด๋ณด๋๋ฐ ํ ๋ฌ์ด ์ง๋ ์ง๊ธ ํฐ ์ด๋ ค์ ์์ด ๊ฐ๋ฐํ๊ณ ์๋ ์ค์ ๋๋ค.
์น ๊ธฐ์ ๋ก ๋ฐ์คํฌํฑ ์ฑ์ ๋ง๋๋๊ฒ ๋๋ฆ ์ฌ๋ฏธ์์ด์ ์น ๊ฐ๋ฐ์ ํด๋ณด์ ๋ถ์ด๋ผ๋ฉด ํ๋ฒ ์ฏค ๋์ ํด๋ด๋ ์ข์ ๊ฒ ๊ฐ์ต๋๋ค.
๋๊ธ