electron+ react + typescript boilerplate 만들기

세니·2024년 8월 29일
0

요구사항

electron도 typescript 코드로 작성, electron의 view도 react 프로젝트로 typescript로 구성하겠습니다.

electron은 로컬에서 쉽게 테스트하기 위해서 수정될 때마다 적용되는 hot-reload 방식으로 development 모드와 상용에서 배포 및 사용하기 위한 production 모드로 구성되어야 합니다.

필요 패키지

npm i -D electron electron-builder typescript nodemon concurrently wait-on cross-env

파일 구조

// folder 
- build // electron 프로젝트를 빌드할 코드
	build.js
- compile // electron의 app.ts를 js로 트랜스파일한 코드
	app.js
- view // electron의 view가 되는 react 프로젝트
	react project
- app.ts // electron의 메인 코드
- package.json
...

필요 scripts 단계

scripts 실행 과정

  • react start : local에서 dev모드로 실행하기 위해서는 react를 우선적으로 시작해야 합니다.
  • react build : prod모드로 실행하기 위해서는 react를 build 해야 합니다.
  • typescript compile : typescript로 작성된 electron 코드를 js 파일로 트랜스 파일 해야 합니다.
  • electron dev start : electron을 dev 모드로 실행합니다.
  • electron prod start : electron을 prod 모드로 실행합니다.
  • electron build : electron 프로젝트를 빌드합니다.

package.json

//package.json
"scripts": {
    "viewstart": "cd view && cross-env BROWSER=none npm run start",
    "viewbuild": "cd view && npm i && npm run build",
    "compile": "tsc",
    "debug": "cross-env ELECTRON_DEBUG=1 electron ./compile/app.js",
    "dev": "concurrently \"npm run viewstart\" \"wait-on http://localhost:3000 && nodemon\"",
    "prestart": "npm run viewbuild && npm run compile",
    "start": "npm run prestart && electron ./compile/app.js",
    "prebuild": "rimraf ./dist",
    "build": "node ./deploy/deploy.js"
  }
  • viewstart : view 폴더 안에 있는 리액트 프로젝트를 브라우저를 열지 않고 실행
  • viewbuild : view 폴더 안에 있는 리액트 프로젝트를 빌드
  • compile : electron ts 파일을 js로 컴파일
  • debug : electron을 development 모드로 실행 후 컴파일 된 js를 실행
  • dev : view 리액트 프로젝트를 실행 후 localhost:3000 이 준비가 되면 nodemon 실행
  • prestart : 리액트 빌드 후 electron 컴파일
  • start : prestart를 실행 후 production 모드로 electron 실행
  • prebuild : electron을 빌드 하기 위한 이전 과정
  • build : electron 빌드

주의할 점

tsconfig

electron에서 ts파일을 js파일로 트랜스 파일링 할 때, view의 react 프로젝트는 제외하도록 tsconfig.json 설정이 필요하다.

어차피 react 프로젝트는 자체적으로 빌드하기 때문이다.

// electron tsconfig.json
"compilerOptions": {
	...
	"outDir": "./compile",
	...
},
"exclude": ["view/*"]

development

development모드로 실행하기 위해서는 환경 변수 설정이 필요합니다.

설정하는 방식에는 여러가지 방식이 있지만 cross-env package를 통해 .env 파일 생성할 필요 없이 명령줄에서 운영체제 상관없이 환경 변수 사용이 가능합니다.

electron이 debug 모드인지 아닌지 체크하는 변수를 생성해 사용하면 됩니다.

cross-env ELECTRON-DEBUG=true

react browser

view 폴더에서 react 프로젝트를 실행할때 npm run start를 하면 localhost3000이 실행되면서 브라우저가 자동으로 띄워집니다.

일렉트론에서는 따로 window를 띄워 확인하기 때문에 브라우저 창을 켰다 닫는 것은 번거롭습니다.

브라우저가 자동으로 open 되는것을 방지하려면 script 명령줄에서BROWSER=none 을 설정해 방지합니다.

이 환경 변수도 마찬가지로 cross-env로 선언하여 사용합니다.

nodemon

electron 파일이 수정될 경우 바로 수정된 부분이 반영이 되도록 nodemon 패키지를 설치해 프로젝트를 재시작합니다.

scripts 명령줄에도 nodemon --exec npm run start 와 같이 작성이 가능하지만 nodemon.json 설정 파일로 명령줄을 짧게 작성할 수 있습니다.

// nodemon.json
{
  "watch": ["app.ts"],
  "ext": "ts js",
  "exec": "npm run compile && npm run debug"
}

react package.json

electron에서 production 모드로 실행하다가 react build한 index.html이 뜨지 않고 빈 화면으로 출력되는 문제가 발생했었고 아래와 같이 터미널 메시지가 띄워져 있었습니다.

The project was built assuming it is hosted at ./.
You can control this with the homepage field in your package.json.

The build folder is ready to be deployed.

Find out more about deployment here:

https://cra.link/deployment

cra는 서버의 루트에서 호스팅된다는 가정 하에 빌드를 생성한다.

homepage 설정을 통해서 cra가 생성된 html 파일에서 사용할 루트 경로를 올바르게 추적이 가능해 상대 경로인 “.”를 설정해주면 된다.

react의 package.json에서 homepage 설정을 해주어야 한다.

// react package.json
{
...
"homepage": ".",
...
}

결과

이렇게 설정한다면 로컬 기준 electron의 app.ts 파일이 수정된다면 다시 재시작되고, react의 코드를 수정한다면 수정 사항이 반영이 됩니다.

electron builder

// build.js
const builder = require('electron-builder');
const package_json = require('../package.json')

builder.build({
  targets: builder.Platform.WINDOWS.createTarget(),
  config: {
    asar: true, // 리소스들 한번에 아카이브
    directories: {
      output: 'dist' // 빌드할 결과물 폴더 저장
    },
    win: {
      target: ['nsis'] // 윈도우용 인스톨러 nsis로 지정
    }
  }
})
  • targets : builder의 Platform을 선택해서 target을 만든다. (linux, windows, mac)
  • config : target을 build할 설정들
profile
세니는 무엇을 하고 있을까

0개의 댓글