일렉트론(Electron) 프로젝트 실행 파일로 패키징 하기 | Node.js

일렉트론(Electron) 프레임워크

웹 기술인 HTML, CSS, JavaScript를 이용한 데스크톱 애플리케이션 제작 프레임워크(Framework)인 일렉트론(Electron)에 대해선 일렉트론(Electron) 프레임워크: 웹 기술로 데스크톱 앱 개발에서 상세하게 다루었다.

기존 웹 브라우저로 HTML 파일을 실행해 사용하던 프로그램을 일렉트론 기반 프로젝트로 변환하고 실행하니 잘 실행 되었다.

이제 애플리케이션을 개발 하였으니 이번 포스팅은 이 개발한 프로젝트 내용을 실행 가능한 애플리케이션으로 압축하고 이를 배포할 수 있는 설치 파일(Installer)로 만드는 방법에 대해 정리한다.

일렉트론(Electron) 패키징 도구

일렉트론을 하나의 실행 파일로 패키징(Pakaging, 배포가 가능한 프로그램으로 묶는 작업) 하기 위해 제공되는 도구로 electron-packager, electron-builder 가 있다.

electron-packager

electron-packager 는 일렉트론 기반 애플리케이션을 패키징하여 각 플랫폼(Windows, Linux, MacOS) 에서 실행 가능한 파일의 형태로 패키징 해주는 도구다.

electron-packager 설치

electron-packager 도 npm 을 통해 설치할 수 있다. 현재 프로젝트의 터미널을 열어 다음 명령어를 입력하여 설치한다.

npm install electron-packager --save-dev
VSCode TERMINAL

터미널에 정상적으로 설치 되었단 메시지가 출력 되면 package.json 에도 잘 추가 되었는지 확인한다.

{
  ...
  "devDependencies": {
    "electron": "^29.2.0",
    "electron-packager": "^17.1.2"
  }
  ...
}
JSON

앱 패키징 하기

electron-packager 를 정상적으로 설치 하였다면 다음 명령어로 앱을 간단하게 패키징 할 수 있다.

npx electron-packager . AppName --platform=win32 --arch=x64
VSCode TERMINAL
  • AppName: 앱(App) 의 이름을 입력하면 되는데 나의 경우 packge.json 안에 name 과 같게 작성 하였다.
  • –platform=win32: Windows 용으로 패키징 하는 옵션이다.
  • –arch=x64: 기반 아키텍쳐를 64비트로 하는 옵션이다.

패키징 된 프로그램은 노드 프로젝트 내의 새 폴더 AppName-win32-x64 형태로 생성된다.

생성 된 프로그램 실행하기

폴더에 접속해 ‘앱 이름.exe’ 를 실행했을 때 정상적으로 실행되면 성공적으로 패키징이 완료된 것이다.

패키징 앱 폴더
패키징 앱 실행

일렉트론 기반으로 만든 프로젝트를 단일 프로그램으로 제작해 보았다. 그런데 패키징을 해보니 이전 포스팅에서 언급하듯, 일렉트론의 리소스, 용량이 단점으로 꼽히는지 알겠다. 😂 무슨 ‘Hello World’ 하나 띄우는 앱이 용량이 170mb 를 넘는다.

그래도 간편한 사용법이 아주 마음에 든다.

electron-builder

electron-builder 는 위의 electron-packager 와 같이 애플리케이션을 배포 가능한 형태로 패키징 하는 도구 지만, 비교적 더 다양한 고급 기능을 지원하고 있다.

예를 들어 개발 된 애플리케이션을 포터블(설치 없이 바로 압축 해제 후 사용) 형태로 제공할 땐 electron-packager 만 사용해도 무방하나, 이를 인스톨러 형태로 만드는 기능은 electron-builder 가 제공하고있다.

무엇보다 일렉트론 프레임워크로 작성 된 앱은 크로미움, Node.js 파일을 포함하여 용량이 크다는 단점이 있는데 인스톨러로 패키징 할 경우 좀 더 적은 용량으로 애플리케이션을 배포할 수 있다는 장점이 있다.

electron-builder 설치

electron-builder 설치를 위해 다음 명령어를 터미널에 입력한다.

npm install electron-builder --save-dev
VSCode TERMINAL

package.json 빌드 구성 추가

터미널에 정상적으로 설치 되었단 메시지가 출력 되면 package.json 에도 다음과 같은 내용들이 포함 되어 있어야 한다. 내용을 자신의 프로젝트에 맞게 아래 JSON 내용을 확인 후 작성해 준다.

{
  "name": "your-app-name",
  "version": "1.0.0",
  "description": "Your App Description",
  "main": "main.js",
  "scripts": {
    "start": "electron .",
    "pack": "electron-builder --dir",
    "dist": "electron-builder"
  },
  "build": {
    "appId": "com.yourcompany.yourapp",
    "productName": "YourAppName",
    "directories": {
      "output": "dist"
    },
    "win": {
      "target": [
        "nsis",
        "zip"
      ]
    },
    "mac": {
      "target": [
        "dmg",
        "zip"
      ]
    },
    "linux": {
      "target": [
        "AppImage",
        "deb"
      ]
    }
  },
  ...
}
JSON
  • scripts 옵션: 터미널에서 사용할 스크립트를 작성한다. 여기서 작성한 스크립트는 “npm run 스크립트명” 으로 터미널에서 실행할 수 있다. 위의 코드에선 dist, pack 을 통해 electron-builder 를 호출하게 된다.
  • build 옵션: 앱 패키징을 위한 설정들이다. 하위의 win, mac, linux 은 각 플랫폼(혹은 OS) 마다 어떤 형태로 방식으로 패키징 될지 지정한 것.

앱 패키징 하기

위의 json 파일까지 정상적으로 작성 하였다면 scripts 안의 설정한 명령어 중 pack 을 통해서 패키징을 수행할 수 있다. 명령어 입력 시 프로젝트 폴더 내 dist 폴더가 생성 되고 win-unpacked 폴더 내에 electron-packager 때와 같이 실행 파일이 생성된다.

npm run pack
VSCode TERMINAL

인스톨러 파일 만들기

위의 scripts 에서 –dir 옵션이 빠진 명령어 dist 를 통해, 프로젝트를 설치가 가능한 형태의 인스톨러 파일로 패키징 할 수 있다.

npm run dist
VSCode TERMINAL

그럼 위의 명령어와 동일하게 dist 폴더 내의 파일들이 생성되며 인스톨러 파일도 함께 생성 된다. 참고로 해당 파일은 개발 환경의 OS 에 맞는 형태로 생성이된다.

npm run dist 명령어로 생성된 인스톨러 파일

설치 경로 변경 가능 설정 법

인스톨러로 설치 시에 사용자가 설치 경로를 설정할 수 있도록 만드는 옵션을 package.json 내에서 설정할 수 있다. 👍(●’◡’●)

빌더 섹션 내 nsis 관련 섹션을 다음과 같이 추가하면 된다.

{
  "build": {
    "appId": "com.yourcompany.yourapp",
    "productName": "YourAppName",
    "directories": {
      "output": "dist"
    },
    "win": {
      "target": [
        "nsis",
        "zip"
      ]
    },
    "nsis": {
      "oneClick": false,
      "allowToChangeInstallationDirectory": true
    },
    ...
}
JSON
  • oneClick: 원클릭 설치를 비활성화 하는 옵션이다. 해당 옵션이 true 가 되면 별도의 과정 없이 앱이 바로 설치되어 false 로 비활성화를 해준다.
  • allowToChangeInstallationDirectory: true 일 경우 설치 시 경로를 설정하는 화면이 출력 된다.

allowToChangeInstallationDirectory 가 true 일 때 생성 된 인스톨러의 설치 과정엔 다음과 같은 화면이 출력 된다.

그 외에 electron-builder 옵션 들

위의 설치 경로 변경 설정 여부와 같이 electron-builder 의 설치 파일에 부여할 수 있는 다양한 옵션이 존재한다.

{
  "build": {
    "nsis": {
      ...
      "allowElevation": true,
      "createDesktopShortcut": true,
      "createStartMenuShortcut": true,
      "uninstallDisplayName": "${productName} Uninstaller"
    }
    ...
}
JSON
  • allowElevation: 프로그램 설치 시 ‘관리자 권한 요청’ 을 허용하는 옵션이다.
  • createDesktopShortcut: 설치 시 데스크탑 바로가기를 만든다.
  • createStartMenuShortcut: 설치 시 시작 메뉴에 바로 가기를 만든다.
  • uninstallDisplayName: 제어판의 프로그램 목록에 표시 될 이름을 지정한다

이 외에 옵션들은 NSIS – electron-builder 공식 문서 에서 상세하게 정리되어 있다.

NSIS 란?

위의 electron-builder 관련 설정 섹션을 확인해보면 nsis 라는 용어가 보일 것이다. nsis 는 Nullsoft Scriptable Install System 의 약자로 Windows 운영 체제를 위해 제공 되는 오픈 소스 기반 설치 생성기(Installer Builder)다.

electron-builder 는 이 nsis 방식을 기본으로 Windows 인스톨러를 패키징 하는데, 풀 네임에서 Scriptable 란 단어가 있는 만큼 package.json 관련 설정 외에 nsis 를 위한 스크립트 코드를 통해서 설치 파일에 다양한 옵션을 부여할 수 있다.

이 내용은 electron-builder: NSIS 설치 프로그램(Installer) 커스터마이징 포스트에 좀 더 상세하게 정리 되어 있다.

설치 생성기(Installer Builder)

설치 생성기는 프로그램을 사용자가 쉽게 설치할 수 있게 해주는 도구들을 뜻하여 위에 언급한 NSIS, Inno Setup, InstallShield 등이 있다.

NSIS 스크립트 사용 설정

인스톨러를 패키징 할 때 사용할 스크립트의 설정은 먼저 프로젝트 폴더 내 확장자 .nsh 를 지닌 파일을 하나 생성하고 이를 build 내 include 섹션에 경로를 지정해주어 설정해야 한다.

package.json
{
  "build": {
    "nsis": {
      "oneClick": false,
      "allowToChangeInstallationDirectory": true,
      "include": "build/installer.nsh"
    },
    ...
}
JSON

NSIS 스크립트 작성

위에서 설정한 경로의 .nsh(예: build/installer.nsh) 파일을 열고 여러가지 스크립트를 작성할 수 있다. 아래 코드는 ChatGPT 가 작성한 기본적은 NSIS 스크립트 코드이다.

아래 코드의 주석들을 확인해 보면 installer 에 다양한 옵션들 (기본 경로 설정, 메시지 박스 출력 등)을 부여할 수 있음을 알 수 있고 이와 관련해선 NSIS Users Manual (sourceforge.io) 공식 문서를 읽고 공부해야 한다.

build/installer.nsh
!define PRODUCT_NAME "YourAppName"

; 기본 설치 경로를 설정합니다.
InstallDir "$LOCALAPPDATA\${PRODUCT_NAME}"

...

ASAR 파일

ASAR 파일은 Atom Shell Archive 의 약자로 일렉트론 프로젝트 기반으로 개발 된 파일들이 아카이브 형식의 파일(압축 된 파일)이다.

프로젝트엔 별도의 파일로 개발 되었던 HTML, JS, CSS 등의 파일들이 하나의 파일로 묶이게 되는 것으로 위의 Electron PackagerElectron Builder 모두에서 기본적으로 패키징 시 생성된다.

Electron Builder 에서 기본 옵션 기준 패키징을 완료하면 패키징 된 앱 폴더 내 resources 안에 파일이 생성된다.

ASAR 파일의 장점

ASAR 파일로 여러 리소스 파일들이 압축되어 있다면 배포 및 관리가 매우 간편해지며 파일이 아예 분리 되어 있을 때 보다 보안 적인 면에서도 이점이 크고 앱의 퍼포먼스에도 긍정적인 결과를 가져온다.

ASAR 파일의 문제

그런데, 실제 일렉트론 앱을 개발하며 ASAR 파일 사용 시 문제가 있었는데 그 중 하나는 바로 “쓰기” 가 불가능 하단 것. 나의 경우 lowdb 모듈을 이용하여 .json 파일에 여러 정보를 읽고 저장 하는 형태의 앱을 개발 하였는데, 상대 경로로 ASAR 내 파일을 읽어 오는 것엔 문제가 없었지만 쓰지 못했다.

그리고 jar, ps1 등의 외부 실행 파일 들 또한 대부분 정상적으로 읽지 못한다. 이런 파일들의 경우 ASAR 로 묶이지 않도록 조치를 취하고 따로 경로를 지정할 방법을 찾아주어야 한다.

ASAR 로 압축 되지 않도록 옵션을 끄는 방법

Electron Builder 에서 이를 간단하게 해결하고 싶다면 package.json 내의 build 섹션에 “asar”: false 를 추가해 주면 된다. 이렇게 되면 resources 폴더 내 파일들이 .asar 파일이 아닌 전부 존재하게 된다.

package.json
"build": {
    "asar": false,
    ...
}

특정 폴더 혹은 파일 ASAR 로 압축하지 않도록 제외하기

위의 옵션은 모든 파일이 압축되지 않는데 이런 경우 앱의 성능과 패키징 속도에 악영향을 줄 수 있으므로 필요한 파일만 제외 시키는 것이 좋다. 이럴 땐 package.json 에서 asarUnpack 이란 옵션에 제외할 경로를 상대 경로로 입력해 주면 된다.

이 경우 같은 resources/app.asar.unpacked 경로에 지정한 폴더, 파일들이 위치하게 된다. 만약 사용 중인 경로에 app.asar 가 포함되어 있을 경우 필요 시 app.asar.unpacked 로 바꿔 주면 앱이 정상으로 동작하게 된다.

예를 들어 아래 코드는 내 프로젝트 내의 bin 폴더 하위의 모든 파일을 제외하는 경로를 지정해준 예시이다.

package.json
"build": {
    "asarUnpack": "bin/*",
    ...
}
0 0 votes
Article Rating
Subscribe
Notify of
guest
0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x
목차
위로 스크롤