Electron - Life Cycle

Posted by Seongkyun Yu on 2021-03-07
Estimated Reading Time 3 Minutes
Words 611 In Total
Viewed Times

Electron Logo

12.0.6 버전을 기준으로 한 설명입니다

초기 설정 이후 본격적으로 Electron 코드를 작성하기 전에 Electron의 생명주기에 대해 알아보자.

Electron Life Cycle

Electron에서 제공하는 app 객체는 Electron의 생명주기를 관리한다.

app 객체를 통해 앱의 라이프 사이클 관련 신호를 받을 수 있다.

app.on('EVENT', ()=>{}) 식으로 받는다.

Event: Ready

app의 준비가 완료 됐을때 이를 감지할 수 있는 방법은

app.on('ready', ()=>{})
app.on('will-finish-launching', ()=>{})
app.whenReady()가 있다.

app.on('ready', ()=>{})는 MAC OS에서 넘겨주는 launchInfo가 필요할 경우 사용한다. launchInfo에는 유저 정보가 담겨있다.

will-finish-launching는 Window와 Linux에서 launchInfo가 필요한 경우 사용한다.

app.whenReady()는 프로미스를 리턴하여 동기화 처리를할 수 있게 만들어준다.

Event: before-quit

window들이 닫히기 시작할 때 발생하는 이벤트이다.

넘겨받는 e객체를 이용하여 e.preventDefault() 호출하면 앱이 종료되는 것을 막을 수 있다.

Event: window-all-closed

window들이 모두 닫혔을 때 발생하는 이벤트이다.

단, app.quit()이 호출되거나 유저가 Cmd + Q를 입력한 경우 발생하지 않는다.

Event: will-quit

window들은 이미 모두 닫혔고, 앱이 종료되기 전 발생하는 이벤트이다.

넘겨받는 e객체를 이용하여 e.preventDefault() 호출하면 앱이 종료되는 것을 막을 수 있다.

Event: quit

앱이 종료될 때 발생하는 이벤트이다.


생명주기를 어느정도 알아보았으니 이제 코드를 작성해 보자.

main.ts

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
import Electron from "electron";
import { app, Menu, BrowserWindow, ipcMain } from "electron";

const APP_WIDTH = 570;
const APP_HEIGHT = isMac ? 570 : 600;
const isMac = process.platform === "darwin";

function createWindow() {
const win = new BrowserWindow({
width: APP_WIDTH,
height: APP_HEIGHT,
webPreferences: {
nodeIntegration: true,
},
resizable: false,
});

win.loadFile("src/renderer/index.html");

return win;
}

// app 시작
app
.whenReady() // 앱이 준비되면
.then(createWindow) // 윈도우 만들기
.then((window: Electron.BrowserWindow) => {
// 메뉴 만들기
Menu.setApplicationMenu(
Menu.buildFromTemplate([
...(isMac ? [{ label: app.name }] : []),

{
label: "File",
submenu: [
{
label: "logger",
click: () => {
//여기에 logger 메뉴를 클릭시 실행할 함수를 넣는다. ex) window.webContents.send(IPC.OPEN_LOGGER, 'open');
},
},
],
},
])
);
});

// Mac의 경우 종료를 해도 최소화 상태가 된 것처럼 만들 수 있다.
// Mac에서 종료 버튼으로 앱을 죽이지 않고 살려두려면 app.quit으로 죽이지 않고 activate 이벤트가 발생 했을때 윈도우만 새로 만든다
app.on("window-all-closed", () => {
if (process.platform !== "darwin") {
app.quit();
}
});

app.on("activate", () => {
if (BrowserWindow.getAllWindows().length === 0) {
createWindow();
}
});

app이 준비되면 createWindow를 이용하여 윈도우를 만드는 간단한 로직이다.

메뉴의 경우 Menu.setApplicationMenuMenu.buildFromTemplate을 통해 생성한다.

메뉴를 만들때 Mac OS의 경우 아무리 app.name을 작성해도 Electron으로 보이는 경우가 있다.

이는 인스톨 파일로 배포할 때 정상적으로 app.name값이 들어가므로 걱정하지 말자.

이제 Renderer Process를 작성하면 끝난다.

index.html

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>Electron</title>
<meta
http-equiv="Content-Security-Policy"
content="script-src 'self' 'unsafe-inline';"
/>
<link rel="stylesheet" href="./Styles/normalize.css" />
<script>
if (typeof module === "object") {
window.module = module;
module = undefined;
}
</script>
<script>
if (window.module) module = window.module;
</script>
<script defer src="./dist/index-bundle.js"></script>
</head>
<body style="background: white;">
<div id="root"></div>
<aside id="modal"></aside>
</body>
</html>

Renderer Process의 경우 일반적인 Front-End 코드를 작성한다고 생각하면 된다.

index.html을 작성하고 Renderer Process 역할을 할 js 파일(ts에서 js로 변환된 index.js)를 import하면 된다.

React처럼 js가 dom을 생성하도록 만들기 위해 root와 modal을 제외한 어떠한 마크업도 남기지 않았지만 꼭 이런 방식으로 작성할 필요는 없다.


If you like this blog or find it useful for you, you are welcome to comment on it. You are also welcome to share this blog, so that more people can participate in it. If the images used in the blog infringe your copyright, please contact the author to delete them. Thank you !