앞선 포스팅에서 발견한 module not found 에러를 검색해보다가, electron-builder
라는 기술을 알게 되었다.
어떤 기술이 electron으로 개발하고 빌드할 때 더 편리하냐인데,
흥미로워서 링크를 가져와봤다.
[링크]electronbuilder_vs_electronforge
읽어보고 나니, 조금 더 많은 빌드 옵션을 제공하는 라이브러리는 electron-builder인듯 하다.
그런데 electron 공식문서에는 electron-forge가 가장 처음 예시로 나와서 electron-forge를 사용했는데... 에러가 자꾸 나니까(물론 내가 뭔가를 잘못설정했을 가능성이 100%이지만...) electron-builder도 사용해보고 싶어진다.
보일러플레이트 레포들을 살펴보면서 디렉토리 구조와 웹팩 설정을 잘 살펴보면서 눈을 트여야겠다.
electron-builder 공식문서에서 소개하는 보일러플레이트
electron-builder에는 electron-builder를 활용한 다양한 보일러플레이트 프로젝트들을 소개해주고 있다.
그 중 나는 electron-react-boilerplate를 선택했다.
현재 내가 설정한 회사 프로젝트는 electron + electron-forge + react + typescript + webpack + tailwindCSS 로 이루어져 있는데, 어떤 차이점이 있는지 비교해보고 싶어졌다.
electron-react-biolderplate의 preload 스크립트가 짜여진 방식이 매우매우 마음에 들어서 복붙해왔다. 내가 preload스크립트를 짤 때 스스로에게 불만이었던 점은 preload스크립트에 매 이벤트마다 이벤트 핸들러를 등록해야하는 점이었다.
그런데 보일러플레이트 코드에서는 ipcRenderer라는 객체에 실제 electron/ipcRenderer 객체를 래핑한 인터페이스 함수를 작성하여 리액트코드에서 조금 더 안전하게 ipcRenderer를 사용할 수 있도록 코드를 작성했다.
이 코드에서 export한 타입들은 기본적으로는 Window객체에 추가가 되지 않으니, preload.d.ts에서 Window 객체에 타입을 추가해준다.
// Disable no-unused-vars, broken for spread args
/* eslint no-unused-vars: off */
import { contextBridge, ipcRenderer, IpcRendererEvent } from 'electron';
export type Channels = 'ipc-example';
const electronHandler = {
ipcRenderer: {
sendMessage(channel: Channels, ...args: unknown[]) {
ipcRenderer.send(channel, ...args);
},
on(channel: Channels, func: (...args: unknown[]) => void) {
const subscription = (_event: IpcRendererEvent, ...args: unknown[]) =>
func(...args);
ipcRenderer.on(channel, subscription);
return () => {
ipcRenderer.removeListener(channel, subscription);
};
},
once(channel: Channels, func: (...args: unknown[]) => void) {
ipcRenderer.once(channel, (_event, ...args) => func(...args));
},
},
};
contextBridge.exposeInMainWorld('electron', electronHandler);
export type ElectronHandler = typeof electronHandler;
//preload.d.ts
import { ElectronHandler } from '../main/preload';
declare global {
// eslint-disable-next-line no-unused-vars
interface Window {
electron: ElectronHandler;
}
}
export {};