nextron 설치
2023-01-18
설치
아래와 같이 명령어를 입력해주면 세팅이 됩니다.
npx create-nextron-app MY_APP --example with-material-ui
빌드 옵션
아래에서 win64 로만 빌드를 해봤습니다.
빌드를 하게 되면, ./dist
폴더 아래에, 설치 파일(exe)이 생성되었습니다.
{
"scripts": {
"build": "nextron build",
"build:all": "nextron build --all",
"build:win32": "nextron build --win --ia32",
"build:win64": "nextron build --win --x64",
"build:mac": "nextron build --mac --x64",
"build:linux": "nextron build --linux"
}
}
main 코드
브라우져와 별개로 pc에서 도는(?) 코드쯤 되는 것 같습니다.
파일의 경로는 ./main/helpers/create-windows.ts
입니다.
그외 ./main/background.ts
같은것도 있는데, 여기서는 윈도우 크기 같은걸 설정할 수 있어 보입니다.
./main/background.ts
에 home 을 보니 home 으로 가장 먼저 접속하는걸 볼수가 있네요.
아래는 클라이언트에서 today 라는 이벤트를 브라우저에서 호출시 pc에서는 데이터를 가져오는 코드입니다.
브라우져에서 api 를 호출해도 되긴 할텐데, cors 같은게 생겨서 외부와 통신이 필요한 코드나 또는 pc 자체에서 먼가 작업을 해야 하는 코드는 여기안에 기술하면 좋습니다.
ipcMain.on('today', (event, arg) => {
const { cookie } = arg
const fetchCall = async () => {
const url = `https://sungsan.silverhug.co.kr/cpcenter/mypage/mysc.php?yy=2022&mm=09&dd=02`;
const result = await fetch(url, {
method: 'GET',
headers: {
Cookie: `PHPSESSID=${cookie}`,
Host: 'sungsan.silverhug.co.kr',
'Accept-Encoding': 'gzip, deflate, br',
Connection: 'keep-alive',
},
})
.then(async res => {
return await res.text().then(res => res)
})
return result
}
fetchCall().then(data => {
const $ = cheerio.load(data);
let list = []
$('#spcontent_wrap > div.myschedule_in > table:nth-child(3) > tbody > tr').map((i, element) => {
let tr = { 시간: '', program: '', 활동내용: '', liveType: '', id: 0, 강의실입장: ''};
tr.id = i+1
tr.시간 = String($(element).find('td:nth-child(1)').text()).split(' ~ ')[0]
tr.program = String($(element).find('td:nth-of-type(2)').text())
tr.활동내용 = String($(element).find('td:nth-of-type(3)').text())
tr.liveType = String($(element).find('td:nth-of-type(4)').text())
tr.강의실입장 = String($(element).find('td:nth-of-type(5)').text())
return list.push(tr)
})
event.reply('today', list)
})
})
ipcMain
ipcMain 같은건 import 해줘야 사용이 가능합니다. 꼭 일렉트론이 아니더라도 필요한 라이브러리는 import 해당
import {
screen,
BrowserWindow,
BrowserWindowConstructorOptions,
ipcMain,
dialog,
} from 'electron';
renderer 코드
여기는 브라우저코드입니다. 동시에 서버 코드도 작성할수 있습니다.
브라우저코드
./main/background.ts
여기서 home으로 가장 먼저 접속했기 때문에,
home 파일을 가장 먼저 열텐데, ./renderer\pages\home.tsx
이 경로가 시작점이라고 볼 수 있습니다.
아래 코드 보시면, 별 다를 것 없는 react 코드임을 알 수 있습니다.
import React from 'react';
import { Theme, makeStyles, createStyles } from '@material-ui/core/styles';
import Boards from '../components/TEMPLATES/Boards'
import Head from "next/head";
import {useEffect, useState} from "react";
import userDataStorage from "../store/userDataStorage";
import { ipcRenderer } from "electron";
import Button from '@mui/material/Button';
import Dialog from '@mui/material/Dialog';
import DialogActions from '@mui/material/DialogActions';
import DialogContent from '@mui/material/DialogContent';
import DialogContentText from '@mui/material/DialogContentText';
import DialogTitle from '@mui/material/DialogTitle';
function Home() {
const [userData, setUserData] = useState({
id: '',
pw: '',
cookie: Date.now(),
});
const [board, setBoard] = useState([])
const [today, setToday] = useState([{
시간: '', program: '', 활동내용: '', liveType: '', id: 0, 강의실입장: ''
}])
const [weather, setWeather] = useState({})
const [open, setOpen] = React.useState(false);
const [msg, setMsg] = React.useState('');
서버 코드
서버 코드는 아래 api
폴더 밑에 존재해야 되는 것 같습니다.
가령 /board
라는 api를 만들고 싶으면,
./renderer\pages\api\board.ts
요렇게 작성하면 됩니다.
코드는 NextApiRequest
, NextApiResponse
이런걸 써줘야 합니다.
예시는 아래와 같습니다.
import type { NextApiRequest, NextApiResponse } from 'next'
const cheerio = require('cheerio');
export default function handler(_req: NextApiRequest, res: NextApiResponse) {
const {
query: { cookie },
method,
} = _req
const fetchCall = async () => {
const url = `https://sungsan.silverhug.co.kr/cpcenter/live/live_list.php`;
const result = await fetch(url, {
method: 'GET',
headers: {
Cookie: `PHPSESSID=${cookie}`,
},
})
.then(async res => {
return await res.text().then(res => res)
})
return result
}
fetchCall().then(data => {
const $ = cheerio.load(data);
let list = []
$('#second-tab > table > tbody > tr').map((i, element) => {
let tr = { 대상: '', 분야: '', 프로그램명: '', 강사명: ''};
tr.대상 = String($(element).find('td:nth-child(1) > p').text())
tr.분야 = String($(element).find('td:nth-of-type(2)').text())
tr.프로그램명 = String($(element).find('td:nth-of-type(3) > p > span').text())
tr.강사명 = String($(element).find('td:nth-of-type(4)').text())
return list.push(tr)
})
res.status(200).json(list)
})
}
여기서 실제로 데이터를 내보내는 부분은 아래 부분입니다.
res.status(200).json(list)
/:{id}
위와 같은걸 만들고 싶으면,
가령 /board
라는 api를 만들고 싶으면,
renderer\pages\api\board\[id].tsx
이 파일을 작성합니다.
예시 코드는 아래와 같습니다.
export default function userHandler(req: NextApiRequest, res: NextApiResponse) {
const {
query: { id, name },
method,
} = req
console.log(req.body)
switch (method) {
case 'GET':
// Get data from your database
res.status(200).json({ id, name: `User ${id}` })
break
case 'PUT':
// Update or create data in your database
res.status(200).json({ id, name: name || `User ${id}` })
break
default:
res.setHeader('Allow', ['GET', 'PUT'])
res.status(405).end(`Method ${method} Not Allowed`)
}
}
함수명이 기본 api 는 handler()
이고, 상세 api 는 userHandler()
로 보입니다.
총총
사실 nextron 구현시 굳이 서버는 쓸필요가 없었던것 같고, main 코드에서 필요한건 다 할수 있을것 같습니다.
db접속 이런것도 main에서는 다 가능할테니 말입니다.
일렉트론에 세세한 설정도 main에서 가능한데, 따로 작성해보진 않았네요.