얼마 전부터 일렉트론으로 무언가를 하고 있는데 슬슬 인스톨러를 붙여볼 시점이 되어 electron-builder의 설정을 뒤적이며 삽질한 결과 몇가지 알게된 것이 기뻐 몇자 끄적여본다.
electron-builder
에서 윈도우용 인스톨러로는 nsis
, appx
, msi
, squirrel
등을 선택할 수 있는데 나는 그 중에 nsis
를 선택했다. 특별한 이유가 있지는 않고 electron-builder
의 기본값이기도 하고 문서에서도 상대적으로 자세하게 설명되어 있기 때문에 선택했다. NSIS는 널소프트 스크립터블 인스톨 시스템의 약자로 추억의 프로그램 윈앰프의 인스톨러를 위해 만들어졌다고 한다.
package.json
을 이용한 설정electron-builder
를 사용할 때는 package.json
파일에 build
설정을 추가할 수 있다. 여기에 입력할 수 있는 옵션들은 홈페이지에 자세히 나와있다. 주소마저 기억하기 쉽다. 그것은 바로 https://electron.build/이다. 가령 내 경우 현재 이 정도 설정을 추가했다.
{
...
"productName": "소중한 앱이름",
"scripts": {
"build": "electron-builder build"
},
"dependencies": {
...소중한 의존모듈님들
},
"devDependencies": {
...소중한 개발의존모듈님들
},
"build": {
"appId": "com.myappid",
"files": [
"나의소중한파일들의경로"
],
"win": {
"target": [{
"target": "nsis",
"arch": [
"x64",
"ia32"
]
}],
"icon": "나의소중한아이콘경로.ico"
},
"nsis": {
"oneClick": false,
"perMachine": true,
"allowToChangeInstallationDirectory": true,
"language": 1042,
"include": "build/installer.nsh",
"shortcutName": "단축아이콘 이름"
},
"directories": {
"output": "빌드를마친파일이가야할경로"
}
}
}
하나씩 살펴보면 다음과 같다.
productName
인스톨러에 표시되는 프로그램 이름을 설정할 때 이 값을 사용한다.
scripts
electron-builder
의 cli 명령은 문서에 잘 나와있다. npm script에 electron-builder build
를 등록하여 사용하고 있다.
build
electron-builder
의 본격적인 설정이다. 이름만 봐도 어느 정도 알 수 있다. 이름만으로 알 수 없는 설정은 다음과 같다.
nsis.oneClick
별도의 경로 설치없이 한방에 설치되게 할 것인가를 설정한다. 기본값은 true
라서 이 설정없이 만든 인스톨러를 실행하면 %APPDATA%
로 설치된다.
nsis.perMachine
사용자별 설치인지 기기 단위 설치인지 설정하는 옵션이다. oneClick
값에 따라서 기본값이 바뀐다고 문서에 설명되어 있다. oncClick
을 false
로 두고 인스톨러를 빌드해서 실행했더니 사용자가 선택하도록 하는 화면이 나왔다. perMachine
을 true
로 해서 선택화면이 나오지 않게 했다.
nsis.allowToChangeInstallationDirectory
사용자가 설치하면서 설치 디렉토리를 변경할 수 있는지 여부이다.
nsis.language
인스톨러의 언어를 지정한다. 설명에는 기본값이 시스템 언어라고 되어 있던데 내가 해보니 영문을 모르겠지만 영어로 나왔다. 여기에는 마이크로소프트의 LCID 값을 넣어줘야 한다고 되어 있다. 그런데 문서에 있는 링크로 가보면 필요한 값이 없어서 좀 더 찾아보니 이런 문서를 발견했다. 한국어는 1042
이다.
nsis.shortcutName
바탕화면에 생성되는 단축아이콘의 이름이다.
nsis.include
NSIS가 사용하는 스크립트를 추가할 수 있다. build/installer.nsh
경로에 파일을 생성한다. 위에서 언급한 것처럼 설치 디렉토리의 기본값이 %APPDATA%
라서 변경하기 위해서 여기에 스크립트를 사용했다. 문서의 경우에는 C:\MyApp
에 설치하도록 설명하고 있는데, C
외의 드라이브를 루트로 사용하는 사람들도 간혹 있기 때문에 불안한 방법이라고 생각되어 조금 더 찾아본 결과 아래와 같이 사용하기로 했다.
Var SystemDrive
!macro preInit
ReadEnvStr $SystemDrive SYSTEMDRIVE
SetRegView 64
WriteRegExpandStr HKLM "${INSTALL_REGISTRY_KEY}" InstallLocation "$SystemDrive\앱이설치될폴더명"
WriteRegExpandStr HKCU "${INSTALL_REGISTRY_KEY}" InstallLocation "$SystemDrive\앱이설치될폴더명"
SetRegView 32
WriteRegExpandStr HKLM "${INSTALL_REGISTRY_KEY}" InstallLocation "$SystemDrive\앱이설치될폴더명"
WriteRegExpandStr HKCU "${INSTALL_REGISTRY_KEY}" InstallLocation "$SystemDrive\앱이설치될폴더명"
!macroend
변수는 !macro
안에 선언할 수 없고 전역에 두어야 하는 모양이다. ReadEnvStr $SystemDrive SYSTEMDRIVE
구문은 변수 $SystemDrive
에 환경변수인 SYSTEMDRIVE를 담도록 하고 있다. 그 아래는 64bit와 32bit 운영체제에 따라 별도의 경로를 설정할 수 있다.
가령 위의 경우처럼 $SystemDrive
대신에 $ProgramFiles64
또는 $ProgramFiles
도 사용할 수 있는 것 같다. ProgramFiles
의 경우에는 별도로 변수를 할당해 주지 않아도 경로 지정이 가능했다.
참고로 잘못된 경로를 넣으면 빌드에 실패한다. 나 같은 경우에는 시스템 드라이브 루트에 설치되게 하기 위해서 삽질을 하다보니 잘못 넣으면 빌드에 실패한다는 사실을 체감하고 말았다.
directories.output
빌드된 인스톨러가 저장되는 경로이다. 별도로 지정하지 않으면 dist
디렉토리에 저장된다.
node-gyp
또는 node-pre-gyp
빌드오류일렉트론을 빌드할 때 네이티브 모듈을 재빌드하곤 하는데, 이유는 알 수 없지만 windows-build-tools
로 설정해놓은 작업환경에서도 빌드가 실패했다. 빌드실패로 생기는 오류가 엉뚱한 점 중의 하나는 빌드에 실패한 후 바이너리 다운로드를 시도하다가 다운로드에 실패한 것으로 나오는 경우이다.
혹시 node-pre-gyp ERR! Tried to download(403):
같은 오류와 함께 URL이 생기는 오류라면 다운로드가 아니라 로컬환경에서 빌드가 되지 않아 생기는 오류를 의심하는 편이 문제를 빨리 해결하는데 도움이 될 것이다. 내 경우에는 sqlite3
로 인해 다음과 같은 오류를 경험했다.
node-pre-gyp ERR! Tried to download(403): https://mapbox-node-binary.s3.amazonaws.com/sqlite3/v4.0.0/electron-v1.8-win32-x64.tar.gz
결론적으로는 node-gyp
빌드가 가능한 환경을 달성하면 된다. 마이크로소프트의 Node.js 가이드라인에 수동 환경설정 과정이 소개되어 있다. 빌드에 성공한 방법은 다음과 같다.
npm config set msvs_version 2015
를 실행한다.이렇게 해도 실패한다면 node_modules
디렉토리를 삭제하고 의존 모듈을 다시 설치해보기를 추천한다. 혹시 그래도 안된다면… 멀리서나마 행운을 빌겠다.