Electron 앱을 빌드하고 배포까지 마쳤다면 과연 끝일까? 대답은 NO. 우리는 지속적으로 유지보수 및 기능개발을 진행해야 한다. 그렇게 하기위해서 업데이트를 진행해야 한다. 이번 글에서는 electron-updater
을 통하여 앱을 자동으로 업데이트 하는 과정을 진행해보겠다.
본 결과물은 @altmshfkgudtjr/electron_example 에서 확인할 수 있습니다.
업데이트를 진행하고, 개발을 보다 원활히 하기 위해서 필요 패키지를 설치해주자.
yarn add electron-updater electron-log
우리는 이제 electron-updater
과 electron-log
를 통해서 업데이트와 로그를 쉽게 기록할 수 있다. 이제 업데이트 관련 코드를 기존에 작성하였던 electron.js
폴더에 아래 코드를 추가해주도록 하자.
// 기존에 작성된 require() 구문 생략...
const { autoUpdater } = require("electron-updater");
const log = require('electron-log');
/** 메인 창 생성 */
function createWindow() {
// ...생략
}
/* Updater ======================================================*/
autoUpdater.on('checking-for-update', () => {
log.info('업데이트 확인 중...');
});
autoUpdater.on('update-available', (info) => {
log.info('업데이트가 가능합니다.');
});
autoUpdater.on('update-not-available', (info) => {
log.info('현재 최신버전입니다.');
});
autoUpdater.on('error', (err) => {
log.info('에러가 발생하였습니다. 에러내용 : ' + err);
});
autoUpdater.on('download-progress', (progressObj) => {
let log_message = "다운로드 속도: " + progressObj.bytesPerSecond;
log_message = log_message + ' - 현재 ' + progressObj.percent + '%';
log_message = log_message + ' (' + progressObj.transferred + "/" + progressObj.total + ')';
log.info(log_message);
})
autoUpdater.on('update-downloaded', (info) => {
log.info('업데이트가 완료되었습니다.');
});
/* Electron =====================================================*/
/** 초기화가 끝나게 되면 실행 */
app.on('ready', () => {
// 메인 창 생성
createWindow();
// 자동 업데이트 등록
autoUpdater.checkForUpdates();
});
/** [생명주기] 모든 창이 닫히면 자동으로 앱 종료 */
app.on('window-all-closed', () => {
app.quit();
});
실행 순서는 다음과 같다. 어플리케이션이 제일 처음 실행되면, autoUpdater.checkForUpdates()
함수를 통해서 checking-for-update
이벤트가 발생한다. 그 후, 업데이트가 가능하다면 update-available
이벤트가, 가능하지 않다면 update-not-available
이벤트가 발동한다.
추가적으로, 해당 업데이트를 디버깅하는 방법은 직접 Electron 앱을 빌드시킨 후에 가능하다. 기존의 yarn electron:xos
또는 yarn electron:window
를 통해서 개발모드로 진행하게 된다면, 다음과 같이 파일을 찾을 수 없다고 에러가 발생한다.
에러가 발생하였습니다. 에러내용 : Error: ENOENT: no such file or directory
그렇다고, 단순히 경로를 http://localhost:3000
이 아닌, index.html
앱을 시작해도 패키징 되지 않는 앱이라면서 업데이트가 진행되지 않는 에러가 발생한다. 그렇기에 번거로워도 직접 앱을 빌드한 후에 진행해야 한다.
업데이트 관련 코드를 모두 작성했다면, 이제 배포를 진행할 차례이다. 기본적으로 Github
의 Public Repository
에서만 추가적으로 코드작성없이 업데이트 기능이 동작한다.
만약 Github
에 올리지 않고 S3
에 올릴 예정이라면 Publish - electron-builder S3Options을 참고하여 추가옵션을 작성하여 배포하면 된다. 또한 Private Repository
여도 해당 레파지토리에 대한 Github Personal access tokens
를 발급받아서 사용할 수도 있다.
아래 예시에서는 공개 저장소에 배포파일을 업로드하여 진행해보겠다.
공개 저장소 우측에 Release
를 클릭한 뒤 나오는 페이지에서 Draft a new release
를 클릭해준다.
package.json
에 적혀있는 배포할 버전을 작성하고, 내용을 작성해준다.
업로드 파일은 아래와 같이 넣어준다.
- MacOS인 경우, latest-mac.yml
, xxx-mac.zip
, xxx.dmg
- Windows인 경우, latest.yml
, xxx.exe
이렇게 업로드를 해주고 나면 이제 앱을 열었을 때, 현재 latest.yml
파일에서 Github에 배포된 파일과 비교하여 버전이 최신이 아닐 경우, 최신 버전의 파일을 다운로드 받아서 앱이 닫히고나서 설치되게 된다. 테스트를 진행해보자. 아래는 v1.0.3
버전에서 v1.0.4
버전으로 업데이트되는 사진이다.
성공적으로 업데이트가 된 것을 확인할 수 있다!
다만, 전자서명이 되지 않은 경우에는 자동으로 업데이트파일이 설치되지 않고, 어플리케이션을 종료하였을 때에 해당 다운로드 파일을 설치하겠냐고 알림 메세지가 뜨게 된다. 이 점 유의하도록 하자.
위 사진에서 볼 수 있는 로그파일은 다음과 같은 경로에서 확인할 수 있다.
%USERPROFILE%\AppData\Roaming\{app name}\logs\{process type}.log
~/Library/Logs/{app name}/{process type}.log
~/.config/{app name}/logs/{process type}.log
사실 가장 짧게 끝난 과정이 아니지 싶다. 하지만, 해당 과정에서 이슈 사항이 있었는데 바로 릴리즈로 배포된 파일명은 NB.1.0.4.dmg
였지만, latest-mac.yml
에 적혀있는 업데이트 파일명은 NB-1.0.4.dmg
여서 딱 한 글자때문에 404 Error가 발생하여 업데이트가 되지않던 이슈였다. 왜 업데이트가 되지않나 싶었더니 딱 저 부분의 문제가 있었다. -___- ...
또한, 처음에는 electron-log
없이 해보려고 했지만, 업데이트 관련 코드를 편하게 확인할 수 없었기에 뒤늦게 로깅을 하는 작업도 했었다 ㅎㅎ..
사실 또 회사 업무로 데스크탑 앱을 직접 배포할 때에는 저렇게 Public Repository
를 이용못할 것 같긴하지만, 지금은 간단하게 흐름을 익혀보자는 느낌으로 그대로 진행하기도 하였다.
참고자료